TypeScript中数组类型校验结果存变量后类型收窄失效问题
现象原因
TS 之所以会出现这个差异,本质是控制流类型收窄的设计限制:
Array.isArray是 TS 内置的类型守卫函数,它的返回值是带类型谓词的input is unknown[],当你直接将它写在if条件中时,TS 可以直接识别这个类型谓词,将条件块内的input类型收窄为unknown[],因此调用map不会报错。- 当你把
Array.isArray(input)的结果赋值给普通变量isArray时,TS 只会将isArray推导为普通的boolean类型,不会保留这个布尔值和input类型之间的绑定关系。编译阶段的类型分析默认不会追踪普通布尔值背后关联的类型判断逻辑,避免带来过高的编译性能开销,因此if (isArray)块中 TS 无法确认input是数组类型,就会抛出类型错误。
复用判断的解决方案
如果需要复用判断逻辑同时保留类型收窄能力,可以自定义类型守卫函数:
// 自定义类型守卫,返回值用类型谓词明确判断结果对应的入参类型 function isUnknownArray(input: unknown[] | string): input is unknown[] { return Array.isArray(input); } function myFunc(input: unknown[] | string) { if (isUnknownArray(input)) { // 此处 input 会被正确收窄为 unknown[] 类型,可正常调用 map return input.map(/* 自定义处理逻辑 */); } return input; }
如果需要适配更多入参类型,可以使用泛型版本的通用数组判断守卫:
function isArray<T>(input: unknown): input is T[] { return Array.isArray(input); }
内容的提问来源于stack exchange,提问作者ebbishop
相关产品推荐
相关产品推荐

