TypeScript如何在不使用as const的情况下获取对象值的联合类型?
解决方案:保留对象key的字面量联合类型
你需要调整泛型参数的定义,让TypeScript能够保留对象中key属性的字面量类型,而不是自动拓宽为string。
实现代码
const getKeys = <const K extends string>(items: { key: K }[]): K => { // 这里可以编写你的函数逻辑,比如返回第一个key或处理所有key的集合 return items[0].key; }; // keys的类型为"foo" | "bar"(符合预期) const keys = getKeys([{ key: "foo" }, { key: "bar" }]); // keys2的类型为"foo" | "qux"(符合预期) const keys2 = getKeys([{ key: "foo" }, { key: "qux" }]);
原理说明
原来的写法中,T extends {key: string}会让TypeScript自动将对象中的字符串字面量(比如"foo")拓宽为string类型,导致返回类型变成string而非预期的字面量联合。
使用<const K extends string>这种const泛型参数(TypeScript 5.0及以上版本支持),会强制TypeScript保留传入值的字面量类型信息,不会进行自动拓宽,从而得到精确的"foo" | "bar"这类联合类型。
如果你的项目使用低于5.0的TypeScript版本,虽然无法完全避免局部类型断言,但可以通过以下方式接近需求(不过不符合你"不能用as const"的要求,仅作补充参考):
const getKeys = <T extends { key: string }>(items: T[]): T["key"] => { return items[0].key; }; // 需在每个key上添加as const const keys = getKeys([{ key: "foo" as const }, { key: "bar" as const }]);
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

