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

TypeScript官方条件类型示例报错,如何修复createLabel函数?

TypeScript条件类型实现createLabel函数的类型错误问题

问题代码与报错

在学习TypeScript条件类型时,尝试实现createLabel函数,代码如下:

interface IdLabel {
  id: number /* some fields */;
}
interface NameLabel {
  name: string /* other fields */;
}
type NameOrId<T extends number | string> = T extends number
  ? IdLabel
  : NameLabel;

function createLabel<T extends number | string>(nameOrId: T): NameOrId<T>  {
  const label: NameOrId<T> = (typeof nameOrId === 'number') ? { id: nameOrId }: { name: nameOrId} ;
  return label;
}

编译时触发类型错误,错误信息:

Type '{ id: number; } | { name: string; }' is not assignable to type 'NameOrId<T>'.
  Type '{ id: number; }' is not assignable to type 'NameOrId<T>'.

错误原因

NameOrId<T>是依赖泛型参数T的分发条件类型,但函数内部的typeof检查属于运行时判断,TypeScript无法将这个判断逻辑和泛型T的静态类型绑定。

编译器只能确定nameOrId是number或string,但无法推导泛型T具体是number、string还是两者的联合类型。因此它会将右侧表达式的类型判定为{id: number} | {name: string},而无法确认该类型与NameOrId<T>完全等价,从而抛出类型不兼容的错误。

解决方案

方案1:类型断言

直接通过类型断言告知编译器右侧表达式的类型匹配NameOrId<T>:

function createLabel<T extends number | string>(nameOrId: T): NameOrId<T>  {
  const label = (typeof nameOrId === 'number') 
    ? { id: nameOrId } as NameOrId<T> 
    : { name: nameOrId } as NameOrId<T>;
  return label;
}

方案2:函数重载

利用函数重载明确不同输入对应的输出类型,类型提示更精准:

interface IdLabel {
  id: number /* some fields */;
}
interface NameLabel {
  name: string /* other fields */;
}

// 重载签名:定义输入输出的类型映射
function createLabel(nameOrId: number): IdLabel;
function createLabel(nameOrId: string): NameLabel;

// 实现签名:处理实际逻辑
function createLabel(nameOrId: number | string): IdLabel | NameLabel {
  return typeof nameOrId === 'number' ? { id: nameOrId } : { name: nameOrId };
}

方案3:分支判断结合类型断言

拆分条件分支,让逻辑更清晰,同时保留泛型写法:

type NameOrId<T extends number | string> = T extends number ? IdLabel : NameLabel;

function createLabel<T extends number | string>(nameOrId: T): NameOrId<T> {
  if (typeof nameOrId === 'number') {
    return { id: nameOrId } as NameOrId<T>;
  } else {
    return { name: nameOrId } as NameOrId<T>;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 19:52:43