如何将字符串类型限定为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
相关产品推荐
相关产品推荐

