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

如何触发变量非never类型的编译错误及断言变量为never类型?

如何断言变量为never类型以处理未覆盖的联合类型分支

要实现「新增type未处理时触发错误」的需求,核心是利用TypeScript对never类型的严格检查:只有类型为never的值才能传入接受never参数的函数,否则会直接触发编译错误;同时保留运行时错误兜底,确保万无一失。

步骤1:编写断言never的工具函数

先定义一个仅接受never类型参数的函数,它会抛出运行时错误,同时返回never类型(让TypeScript知道这个函数不会正常返回):

function assertNever(value: never): never {
  throw new Error(`未处理的job.type: "${(value as any).type}"`);
}

步骤2:在未覆盖的分支调用该函数

在条件判断的最后一个else分支里调用这个函数,传入当前的job变量:

  • 当所有type分支都被处理时,job的类型会被收窄为never,此时调用assertNever完全符合类型要求,编译通过。
  • 当新增了type但忘记处理时,job的类型会是新增的那个联合分支(而非never),调用assertNever会直接触发编译错误,提示「类型XXX不能赋值给类型never」,让你在部署前就发现问题。

优化后的完整代码示例:

type Job = { type: 'add'; payload: any } | { type: 'send'; payload: any };

const handleJob = (job: Job) => {
  // 优化:用Extract提取具体分支类型,让函数参数更严谨
  const add = (job: Extract<Job, { type: 'add' }>) => {
    console.log('处理add任务:', job.payload);
  };
  const send = (job: Extract<Job, { type: 'send' }>) => {
    console.log('处理send任务:', job.payload);
  };

  if (job.type === 'add') {
    add(job);
  } else if (job.type === 'send') {
    send(job);
  } else {
    // 新增type未处理时,此处编译报错
    assertNever(job);
  }
};

function assertNever(value: never): never {
  throw new Error(`未处理的job.type: "${(value as any).type}"`);
}

效果验证

比如给Job新增一个delete类型:

type Job = { type: 'add'; payload: any } | { type: 'send'; payload: any } | { type: 'delete'; payload: any };

此时handleJob的else分支里,job的类型是{ type: 'delete'; payload: any },调用assertNever(job)会直接触发编译错误,提醒你必须新增对应的处理分支。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:52:50