如何将传入数组元素的属性作为类中另一个参数的类型?
实现基于动态entries的handler参数类型推断
你想要的效果完全可以实现,核心是通过泛型参数捕获entries中name属性的具体字面量类型,从而让handler的参数自动推断为这些字面量的联合类型。
解决方案1:捕获数组元素类型
class Test<T extends { name: string }> { constructor( public options: { entries: T[]; handler: (entryName: T["name"]) => void; } ) {} } const test = new Test({ entries: [{ name: "a" }, { name: "b" }, { name: "c" }], handler(name) { // name 类型自动推断为 "a" | "b" | "c" console.log(name); }, });
解决方案2:直接捕获name的联合类型
如果想让泛型更聚焦于name的类型,可以简化写法:
class Test<Name extends string> { constructor( public options: { entries: { name: Name }[]; handler: (entryName: Name) => void; } ) {} } const test = new Test({ entries: [{ name: "a" }, { name: "b" }, { name: "c" }], handler(name) { // name 类型为 "a" | "b" | "c" }, });
为什么最初的写法不生效?
你最初的代码中,entries被定义为{ name: string }[],TypeScript会将name识别为宽泛的string类型,不会保留数组中具体的字面量值。而通过泛型T或Name,TypeScript会自动推断出传入的entries中name的具体字面量联合类型,再将这个类型绑定到handler的参数上,实现精准约束。
ChatGPT的回答并不准确,TypeScript的编译时类型系统完全支持这种基于泛型的关联类型推断,这种模式在很多主流TypeScript库中都有应用。
内容的提问来源于stack exchange,提问作者dodov
相关产品推荐
相关产品推荐

