如何触发变量非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
相关产品推荐
相关产品推荐

