TypeScript条件类型createLabel报错:类型'{ id: number; }'无法赋值给NameOrId<T>,如何解决?
解决TypeScript条件类型返回值不匹配的错误
你的代码报错是因为TypeScript无法在函数内部自动将分支返回值和泛型条件类型NameOrId<T>关联起来。泛型T是在函数调用时确定的,函数内部的typeof类型检查没法让TS推断出当前分支对应的NameOrId<T>具体类型。
下面是两种可行的解决方法:
方法一:使用类型断言
直接在每个返回分支将值断言为NameOrId<T>,明确告诉TS当前返回值符合泛型条件类型的要求:
interface nameLabel { name: string } interface idLabel { id: number } type NameOrId<T> = T extends number ? idLabel : nameLabel; function createLabel<T extends number | string>(idOrName: T): NameOrId<T>{ if (typeof idOrName === 'number') { return { id: idOrName } as NameOrId<T>; } else { return { name: idOrName } as NameOrId<T>; } } const d = createLabel(2); // 类型为idLabel,正常推断
方法二:使用函数重载
相比泛型条件类型,函数重载能更清晰地定义输入类型和返回类型的对应关系,TS也能更好地进行类型检查:
interface nameLabel { name: string } interface idLabel { id: number } // 重载签名:定义输入输出的对应关系 function createLabel(idOrName: number): idLabel; function createLabel(idOrName: string): nameLabel; // 实现签名:处理具体逻辑 function createLabel(idOrName: number | string): idLabel | nameLabel { if (typeof idOrName === 'number') { return { id: idOrName }; } else { return { name: idOrName }; } } const d = createLabel(2); // 类型为idLabel const e = createLabel("Alice"); // 类型为nameLabel
两种方法都能解决报错问题,如果你需要保留泛型的灵活性,选方法一;如果希望类型定义更直观清晰,方法二更合适。
内容的提问来源于stack exchange,提问作者chengfengwang
相关产品推荐
相关产品推荐

