TypeScript中已声明类型但secondLastBlock被推断为never类型的原因
TypeScript中while语句里secondLastBlock被推断为never类型的原因分析
问题描述
TypeScript编译器在while语句中提示secondLastBlock为never类型,报错:
Property 'color' does not exist on type 'never'.(2339)
复现代码
export interface IBlock { color: string; } const testAray: IBlock[] = [ { color: "green" }, { color: "red" }, { color: "yellow" }, { color: "blue" } ] const colors = [ "green", "red", "yellow", "blue" ] let secondLastBlock: IBlock | null = null; let lastBlock: IBlock | null = null; for (const block of testAray) { while ( block.color === secondLastBlock?.color && block.color === lastBlock?.color ) { block.color = colors[ Math.ceil(Math.random() * 4) ] } secondLastBlock = lastBlock; lastBlock = block; }
原因分析
这是TypeScript的类型推断逻辑导致的:
- 第一次进入for循环时,
secondLastBlock和lastBlock都是null,此时secondLastBlock?.color和lastBlock?.color都会返回undefined。而block.color是字符串类型,字符串和undefined做===比较结果必然是false,所以while循环的条件第一次肯定不成立,循环体根本不会执行。 - TypeScript编译器会基于这个逻辑做控制流分析,它认为在while循环内部时,
secondLastBlock和lastBlock必须满足“能让条件为true”的状态,但实际上第一次循环时这两个变量都是null,条件不可能为true,后续循环中虽然变量会被赋值,但编译器没正确追踪到循环迭代间的类型变化,反而推断出在while循环内部这两个变量的类型是never(因为没有任何类型能让条件成立)。 - 简单说就是编译器过度优化了控制流分析,没考虑到for循环迭代过程中变量会被更新,错误地把while内部的
secondLastBlock和lastBlock类型缩小成了never,自然就找不到color属性了。
内容的提问来源于stack exchange,提问作者Heeiiigou
相关产品推荐
相关产品推荐

