如何基于判别式缩小TypeScript函数的返回类型范围?
问题分析
这段代码的核心问题是TypeScript无法自动关联输入参数的具体值和返回值类型——它会把Method的返回类型推断为number | string的联合类型。哪怕你传入明确的常量"a",变量Result的类型依然是number | string,而非预期的精确number类型,丢失了类型系统应该提供的精确性。
修正方案
方案1:函数重载(最直观的显式声明)
通过函数重载可以直接为不同参数值指定对应的返回类型:
type Value = "a" | "b"; // 重载签名:定义参数与返回值的对应关系 function Method(value: "a"): number; function Method(value: "b"): string; // 实现签名:处理实际逻辑 function Method(value: Value) { if (value === "a") return 1000; else return "word"; } const Result = Method("a"); // 类型为number const Result2 = Method("b"); // 类型为string
方案2:条件类型(用类型系统推导)
利用条件类型让返回类型依赖于输入参数的具体类型:
type Value = "a" | "b"; // 定义参数到返回值的类型映射规则 type ReturnTypeForValue<T extends Value> = T extends "a" ? number : string; function Method<T extends Value>(value: T): ReturnTypeForValue<T> { // 需要类型断言来让TS认可返回值符合条件类型 if (value === "a") return 1000 as ReturnTypeForValue<T>; else return "word" as ReturnTypeForValue<T>; } const Result = Method("a"); // 类型为number const Result2 = Method("b"); // 类型为string
方案3:对象映射(易扩展维护)
如果后续需要新增Value的取值,这种方式更易扩展,同时能保留字面量类型的精确性:
type Value = "a" | "b"; // 用const断言固定映射对象的字面量类型 const ReturnValueMap = { a: 1000, b: "word" } as const; // 从映射对象推导返回类型 type ReturnTypeForValue = typeof ReturnValueMap[Value]; function Method(value: Value): ReturnTypeForValue { return ReturnValueMap[value]; } const Result = Method("a"); // 类型为1000(字面量number) const Result2 = Method("b"); // 类型为"word"(字面量string)
内容的提问来源于stack exchange,提问作者razgraf
相关产品推荐
相关产品推荐

