TypeScript:能否将类型属性用作类型?实现对象与函数类型关联
TypeScript自动推断FruitPicker的泛型参数
问题背景
需要让FruitPicker对象的函数参数类型、返回值类型与其自身的availableFruits、fruitKey属性自动关联,且无需手动传递泛型参数。
初始代码尝试:
type Banana = { type: "banana" }; type Apple = { type: "apple" }; type Peach = { type: "peach" }; type Lookup = { banana: Banana; apple: Apple; peach: Peach; }; type FruitPicker = { (deliveredFruits: /* 需关联availableFruits的类型 */) => Lookup[this.fruitKey]; fruitKey: keyof Lookup; availableFruits: (keyof Lookup)[]; }; // 实现示例 const fruitPicker: FruitPicker = (deliveredFruits) => { return { type: "banana" }; }; fruitPicker.fruitKey = "banana"; fruitPicker.availableFruits = ["apple", "peach"];
通过泛型实现了类型关联,但必须手动指定泛型参数:
type FruitPicker<Key extends keyof Lookup, AvailableFruits extends keyof Lookup> = { (availableFruits: Pick<Lookup, AvailableFruits>) => Lookup[Key]; fruitKey: Key; availableFruits: AvailableFruits[]; };
解决方案:使用工厂函数实现自动推断
直接声明对象时TypeScript无法自动推导泛型,但可以通过工厂函数,让TS根据传入的配置自动推断泛型参数:
type Banana = { type: "banana" }; type Apple = { type: "apple" }; type Peach = { type: "peach" }; type Lookup = { banana: Banana; apple: Apple; peach: Peach; }; // 泛型工厂函数,自动推导Key和Available类型 function createFruitPicker<Key extends keyof Lookup, Available extends keyof Lookup>( config: { fruitKey: Key; availableFruits: Available[] }, pickerFn: (delivered: Pick<Lookup, Available>) => Lookup[Key] ): FruitPicker<Key, Available> { const picker = pickerFn as FruitPicker<Key, Available>; picker.fruitKey = config.fruitKey; picker.availableFruits = config.availableFruits; return picker; } // 使用示例:无需手动传泛型,TS自动推断所有类型 const fruitPicker = createFruitPicker( { fruitKey: "banana", availableFruits: ["apple", "peach"] }, (deliveredFruits) => { // deliveredFruits自动推断为Pick<Lookup, "apple" | "peach"> // 返回值必须符合Banana类型 return { type: "banana" }; } ); // 类型验证: fruitPicker.fruitKey; // 类型为"banana" fruitPicker.availableFruits; // 类型为("apple" | "peach")[] fruitPicker({ apple: { type: "apple" }, peach: { type: "peach" } }); // 返回Banana类型
方案说明
- 工厂函数通过接收
config参数,让TypeScript自动提取fruitKey和availableFruits的类型作为泛型参数 - 最终返回的
FruitPicker实例,函数参数、返回值与对象属性的类型完全关联,无需手动指定泛型
内容的提问来源于stack exchange,提问作者bitrevolution
相关产品推荐
相关产品推荐

