如何让TypeScript函数根据输入参数返回精确类型而非联合类型
解决TypeScript函数输入对应特定输出类型的问题
要让USE_TYPE函数根据输入的"A"或"B"返回对应类型的my_choice(而非联合类型),可以通过泛型+类型映射或函数重载两种方式实现,以下是具体方案:
方案一:泛型+类型映射(推荐,易扩展)
通过建立字符串类型与类的映射关系,结合泛型捕获输入的具体类型,让TypeScript推导对应输出类型:
class A { specifically_for_a() { return "A"; } } class B { specifically_for_b() { return "b"; } } // 定义字符串类型到对应类的映射 type TypeMap = { "A": A; "B": B; }; // 泛型函数,约束输入类型为TypeMap的键 function USE_TYPE<T extends keyof TypeMap>(type: T) { return { choices: ["A", "B"] as const, // 让choices类型精确为只读["A", "B"] get my_choice(): TypeMap[T] { if (type === "A") { return new A() as TypeMap[T]; } else { return new B() as TypeMap[T]; } } }; } // 测试:此时a.my_choice类型为A,可直接调用specifically_for_a const a = USE_TYPE("A"); a.my_choice.specifically_for_a(); // 测试:此时b.my_choice类型为B,可直接调用specifically_for_b const b = USE_TYPE("B"); b.my_choice.specifically_for_b();
关键说明:
TypeMap:将输入的字符串标识与目标类类型绑定,为TypeScript提供类型推导依据。- 泛型
T:捕获调用时传入的具体字符串类型("A"或"B"),而非模糊的联合类型。 as const:确保choices的类型是精确的字符串数组,而非宽泛的string[]。- 类型断言
as TypeMap[T]:在分支返回时明确类型,帮助TypeScript完成泛型推导。
方案二:函数重载(适合简单场景)
通过为函数定义多个重载签名,直接指定不同输入对应的输出类型:
class A { specifically_for_a() { return "A"; } } class B { specifically_for_b() { return "b"; } } // 重载签名:指定不同输入对应的输出类型 function USE_TYPE(type: "A"): { choices: ["A", "B"], my_choice: A }; function USE_TYPE(type: "B"): { choices: ["A", "B"], my_choice: B }; // 实现函数 function USE_TYPE(type: "A" | "B") { return { choices: ["A", "B"] as const, get my_choice() { if (type === "A") { return new A(); } else { return new B(); } } }; } // 测试 const a = USE_TYPE("A"); a.my_choice.specifically_for_a(); // 类型正确 const b = USE_TYPE("B"); b.my_choice.specifically_for_b(); // 类型正确
关键说明:
- 重载签名直接声明了输入
"A"时返回带A类型my_choice的对象,输入"B"时返回带B类型的对象。 - 实现函数仍使用联合类型参数,但TypeScript会根据重载签名推导调用时的返回类型。
内容的提问来源于stack exchange,提问作者A. L
相关产品推荐
相关产品推荐

