You need to enable JavaScript to run this app. TypeScript中如何将branded字符串类型用作Record类型的索引
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何将branded字符串类型用作Record类型的索引

你遇到的报错是TypeScript类型检查器的现有限制导致的:带品牌标记的字符串交叉类型虽然本质是string的子类型,也可以作为Record的第一个泛型参数传入,但类型检查器目前不会自动将其识别为合法的索引类型,所以用该类型的值作为索引取值时会抛出错误。

方案1:自定义带索引签名的接口替代Record语法糖

这是最简洁无侵入的方案,直接声明索引键的类型为Foo即可:

type Foo = string & { _fooBrand: undefined }
// 不用Record,自定义索引签名接口
interface T {
  [key: Foo]: string
}
const f = (a: T, b: Foo) => {
  const c = a[b] // 无类型报错,类型推断正确为string
}

方案2:取值时显式转字符串

如果不想修改原有类型定义,利用Foo是string子类型的特性,取值时转为字符串即可,运行时无任何额外开销:

type Foo = string & { _fooBrand: undefined }
type T = Record<Foo, string>
const f = (a: T, b: Foo) => {
  const c = a[b as string] // 无类型报错
}

方案3:使用模板字符串类型包装键类型

如果你必须保留Record的写法,可以用模板字符串语法让TS识别到这是合法的字符串键:

type Foo = string & { _fooBrand: undefined }
type T = Record<`${Foo}`, string>
const f = (a: T, b: Foo) => {
  const c = a[b] // 无类型报错
}

注意:Foo类型的取值必须通过合规的校验逻辑生成,避免非法值混入破坏类型安全,你可以搭配类型守卫使用:

function isFoo(str: string): str is Foo {
  return str.startsWith('foo')
}

所有方案都不会影响运行时逻辑,品牌标记仅在编译阶段做类型校验用,运行时Foo类型的值就是普通字符串。

内容的提问来源于stack exchange,提问作者david_adler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 02:54:01