如何创建返回继承自联合类型的泛型类型的TypeScript函数
问题说明
首先你的代码存在两处基础语法错误,且当前MakeCoffee的泛型设计本身不可行:
interface类型定义时不需要赋值等号,原代码中interface Cappuccino = { ... }属于语法错误- TypeScript的类型信息会在编译阶段完全擦除,运行时不存在任何类型、泛型相关的元数据,你定义的无参泛型函数
function MakeCoffee<T extends Coffee>(): T,在函数内部根本无法判断T到底是Latte、Cappuccino还是其他子类型,不可能正确构造返回值。 - 原代码中
IceLatte类型没有被纳入Coffee联合类型,后续使用时会被判定为不属于Coffee范畴。
修正后的类型定义
先把基础类型的语法错误修正:
interface Latte { ouncesEspresso: number; milkToEspresso: 4; } interface Cappuccino { ouncesEspresso: number; milkToEspresso: 2; } interface IceLatte extends Latte { icePortion: "light" | "normal" | "extra"; } type Coffee = Latte | Cappuccino | IceLatte;
可行的实现方案
推荐通过传入咖啡类型标识+必填参数的方式实现,配合函数重载保证类型安全:
// 支持的咖啡类型标识 type CoffeeType = "latte" | "cappuccino" | "iceLatte"; // 重载签名:精准匹配不同咖啡的入参和返回类型 function MakeCoffee(type: "latte", espressoOunces: number): Latte; function MakeCoffee(type: "cappuccino", espressoOunces: number): Cappuccino; function MakeCoffee(type: "iceLatte", espressoOunces: number, icePortion: IceLatte["icePortion"]): IceLatte; // 函数内部实现 function MakeCoffee( type: CoffeeType, espressoOunces: number, icePortion?: IceLatte["icePortion"] ): Coffee { switch (type) { case "latte": return { ouncesEspresso: espressoOunces, milkToEspresso: 4 }; case "cappuccino": return { ouncesEspresso: espressoOunces, milkToEspresso: 2 }; case "iceLatte": if (!icePortion) throw new Error("制作冰拿铁必须指定冰量"); return { ouncesEspresso: espressoOunces, milkToEspresso: 4, icePortion }; default: throw new Error("不支持的咖啡类型"); } }
调用时TS会自动根据传入的类型标识推断返回值类型,不需要手动指定泛型:
const regularLatte = MakeCoffee("latte", 2); // 自动推导为Latte类型 const cappuccino = MakeCoffee("cappuccino", 1); // 自动推导为Cappuccino类型 const iceLatte = MakeCoffee("iceLatte", 2, "extra"); // 自动推导为IceLatte类型
不要尝试写无参泛型的实现,哪怕你用类型断言强行返回某个对象,也无法保证运行时返回值和调用方指定的泛型类型一致,会埋下类型安全隐患。
内容的提问来源于stack exchange,提问作者Philip
相关产品推荐
相关产品推荐

