如何用TypeScript泛型从对象数组提取可用ID联合类型?
如何从对象数组中提取所有ID的联合类型
解决方案
要实现从对象数组中提取所有ID的联合类型,核心是保留数组中每个元素ID的字面量类型,避免TypeScript将其自动拓宽为string。以下是两种可行的实现方式:
方法1:使用as const固化数组类型
const myValues = [ {id: 'abc', label: 'anyLabelForAbc'}, {id: 'xyz', label: 'anyLabelForXyz'}, {id: 'foo', label: 'anyLabelForFoo'}, {id: 'bar', label: 'anyLabelForBar'}, ] as const; // 通过as const让TypeScript推断出字面量类型的元组 // 定义泛型类型提取ID联合 type AvailableIds<T extends readonly { id: string }[]> = T[number]['id']; // 使用示例 const availableIds: AvailableIds<typeof myValues> = 'abc'; // 类型提示为 'abc' | 'xyz' | 'foo' | 'bar'
方法2:让TypeScript自动推断元组类型
如果你不想用as const,可以不手动给数组指定宽泛的Item[]类型,让TypeScript自动推断包含字面量类型的元组:
// 不给数组显式标注类型,让TS自动推断 const myValues = [ {id: 'abc', label: 'anyLabelForAbc'}, {id: 'xyz', label: 'anyLabelForXyz'}, {id: 'foo', label: 'anyLabelForFoo'}, {id: 'bar', label: 'anyLabelForBar'}, ]; type AvailableIds<T extends { id: string }[]> = T[number]['id']; const availableIds: AvailableIds<typeof myValues> = 'xyz'; // 同样能得到正确的联合类型提示
原有代码失效的原因
你之前的代码中,给数组显式标注了Item[]类型:
const items: Item[] = [/* ... */];
由于Item定义里id是string类型,TypeScript会把数组中所有元素的id都拓宽为通用的string,而非保留各自的字面量类型('abc'、'xyz'等)。因此后续泛型Ids<typeof items>只能得到string类型,自然没有代码提示。
另外,你定义的Index<T>类型是多余的,直接用T[number]就能获取数组元素的联合类型,再取['id']即可得到所有ID的联合。
内容的提问来源于stack exchange,提问作者Marcel Armada-Castellon
相关产品推荐
相关产品推荐

