You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将字符串类型限定为TypeScript只读数组的静态id集合?

解决TypeScript中提取只读数组元素字面量ID类型的问题

问题核心在于:你定义的HasID接口里id是string类型,不管用Readonly<HasID[]>直接注解变量,还是用satisfies做约束,TypeScript都会把数组中id的字面量值自动拓宽成string,导致无法提取出"foo" | "bar"这种具体的联合类型。

下面是两种可行的解决方法:

方法一:结合as const与satisfies

用as const强制TypeScript保留数组元素的字面量类型,同时通过satisfies确保数组结构符合HasID的要求,兼顾类型校验和字面量保留:

interface HasID {
  id: string
  info?: any
}

const storage = [
 { id: 'foo' },
 { id: 'bar', info: ['baz'] }
] as const satisfies Readonly<HasID[]>

// 现在能正确得到 "foo" | "bar"
type StorageID = (typeof storage)[number]['id']

方法二:泛型函数约束

通过泛型函数接收数组,利用as const传入字面量数组,同时让泛型参数继承Readonly<HasID[]>来做类型校验:

interface HasID {
  id: string
  info?: any
}

function createStorage<T extends Readonly<HasID[]>>(arr: T) {
  return arr
}

const storage = createStorage([
 { id: 'foo' },
 { id: 'bar', info: ['baz'] }
] as const)

type StorageID = (typeof storage)[number]['id'] // "foo" | "bar"

原理说明:as const会将数组和对象的所有属性都标记为只读的字面量类型,阻止TypeScript做类型拓宽,这样后续提取id类型时就能拿到具体的字面量联合类型,而不是被拓宽后的string。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 22:45:08