如何让TypeScript接口根据指定键自动推断Options泛型类型?
TypeScript:根据属性值推断泛型类型的接口实现
编辑:解决方案已给出
我定义了一个接收文本键名和值键名作为泛型参数的TypeScript泛型类型Options<T, TKey, VKey>,其中TKey为文本键,VKey为值键。
/** * 我的类型定义 */ type Option< T, TKey extends PropertyKey, VKey extends PropertyKey > = { [key: PropertyKey]: unknown } & { [K in TKey]: string } & { [K in VKey]: T }; type Options< T = unknown, TKey extends PropertyKey = "text", VKey extends PropertyKey = "value" > = Array<Option<T, TKey, VKey>>;
问题描述
如何编写一个TypeScript接口,使其能根据传入的textProperty和valueProperty的值,正确推断Options<T, TKey, VKey>类型?
我尝试定义了如下接口,但无法实现预期的类型推断:
// 定义的接口(无法正确推断类型) interface MySelectProps<T> { value: T; textProperty: PropertyKey; // 默认值为'text' valueProperty: PropertyKey; // 默认值为'value' options: Options<T, MySelectProps<T>['textProperty'], MySelectProps<T>['valueProperty']>; }
期望效果
当传入不同的textProperty和valueProperty值时,options的类型能自动匹配:
// 示例1:options应推断为Options<string, "label", "value"> const myProps: MySelectProps<string> = { value: "1", textProperty: "label", valueProperty: "value", options: [/* ... */] } // 示例2:options应推断为Options<string, "myTextProperty", "myValueProperty"> const myProps2: MySelectProps<string> = { value: "1", textProperty: "myTextProperty", valueProperty: "myValueProperty", options: [/* ... */] }
解决方案
要实现这种基于属性值的类型推断,需要将MySelectProps定义为包含TKey和VKey两个额外泛型参数的泛型接口,并为这两个参数设置默认值,同时让textProperty和valueProperty的类型绑定到对应的泛型参数上:
// 修正后的泛型接口 interface MySelectProps<T, TKey extends PropertyKey = "text", VKey extends PropertyKey = "value"> { value: T; textProperty: TKey; valueProperty: VKey; options: Options<T, TKey, VKey>; }
验证效果
现在TypeScript可以根据传入的textProperty和valueProperty的字面量值,自动推断出TKey和VKey的类型,进而约束options的结构:
// 示例1:自动推断TKey为"label",VKey为"value" const myProps = { value: "1", textProperty: "label", valueProperty: "value", options: [{ label: "选项1", value: "1" }, { label: "选项2", value: "2" }] } satisfies MySelectProps<string>; // 示例2:自动推断TKey为"myTextProperty",VKey为"myValueProperty" const myProps2 = { value: "1", textProperty: "myTextProperty", valueProperty: "myValueProperty", options: [{ myTextProperty: "选项A", myValueProperty: "1" }] } satisfies MySelectProps<string>;
如果需要显式指定类型,也可以直接传递泛型参数:
const myProps3: MySelectProps<number, "name", "id"> = { value: 1, textProperty: "name", valueProperty: "id", options: [{ name: "张三", id: 1 }, { name: "李四", id: 2 }] };
内容的提问来源于stack exchange,提问作者James St-Pierre
相关产品推荐
相关产品推荐

