You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript泛型条件返回类型报错问题求助

TypeScript泛型条件类型返回值类型错误分析与修复

问题原因

你这里的函数返回类型是基于泛型Mode的条件类型,但TypeScript编译器在函数内部无法将分支判断(比如mode === 'A')和泛型条件类型的结果做关联。因为Mode是一个扩展OptionMode的泛型参数,它可能是单个类型,也可能是联合类型,编译器没办法在每个分支里确定Mode extends 'A'的最终结果,所以会认为string或number都不能匹配条件类型的返回值要求。

解决方案

方案1:使用类型断言

直接在每个返回值后添加类型断言,明确告诉编译器当前分支的返回值符合条件类型要求:

type OptionMode = 'A' | 'B' | 'C';

const Foo = <Mode extends OptionMode>(
  mode: Mode
): Mode extends 'A' ? string : number => {
  if (mode === 'A') {
    return 'This is a string' as Mode extends 'A' ? string : number;
  } else {
    return 1 as Mode extends 'A' ? string : number;
  }
};

const stringResult = Foo('A'); // 类型为string
const numberResult = Foo('B'); // 类型为number

方案2:使用函数重载(更推荐)

函数重载能明确指定不同输入对应的返回类型,编译器可以精准推断,类型安全性更高:

type OptionMode = 'A' | 'B' | 'C';

// 重载签名:定义不同输入输出的对应关系
function Foo(mode: 'A'): string;
function Foo(mode: Exclude<OptionMode, 'A'>): number;
// 实现签名:函数内部的实际逻辑
function Foo(mode: OptionMode): string | number {
  if (mode === 'A') {
    return 'This is a string';
  } else {
    return 1;
  }
};

const stringResult = Foo('A'); // 类型为string
const numberResult = Foo('B'); // 类型为number

方案3:自定义类型守卫配合泛型

如果需要保留泛型写法,可以通过自定义类型守卫让编译器正确识别分支的类型:

type OptionMode = 'A' | 'B' | 'C';

// 自定义类型守卫,帮助编译器窄化mode的类型
const isModeA = <Mode extends OptionMode>(mode: Mode): mode is Mode & 'A' => {
  return mode === 'A';
};

const Foo = <Mode extends OptionMode>(
  mode: Mode
): Mode extends 'A' ? string : number => {
  if (isModeA(mode)) {
    return 'This is a string' as ReturnType<typeof Foo<Mode>>;
  } else {
    return 1 as ReturnType<typeof Foo<Mode>>;
  }
};

const stringResult = Foo('A'); // 类型为string
const numberResult = Foo('B'); // 类型为number

内容的提问来源于stack exchange,提问作者A.A

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 00:46:33