为什么TypeScript无法对数组类型进行类型收窄?有什么更优解决方案?
1. TypeScript无法实现该场景数组类型收窄的原因
TypeScript的控制流分析逻辑默认不会修改变量初始声明绑定的根类型,你示例中的input参数在声明时就被固定为(string | number)[]类型,哪怕你给它重新赋值了map返回的string[]类型值,TS也不会自动更新这个变量的根类型。
核心原因是数组属于可变容器类型,如果TS自动将重赋值后的数组类型收窄,后续如果有往数组中插入不符合收窄后类型的元素的操作,TS就会出现漏判,为了保证整体类型安全,TS没有做这类容器的自动收窄逻辑。
2. 可选的优化方案
你目前使用的直接返回map结果、或者赋值给新const变量的方案,本身就是TypeScript官方推荐的最佳实践,没有额外性能开销,类型安全性最高,不属于需要规避的“不好的写法”。
如果一定要复用原有变量名,可以用以下两个方案:
- 方案1:通过临时中转变量让TS自动推导类型
function test(input: (string | number)[]): string[] { let temp = input temp = temp.map(x => x.toString()) return temp }
这里的temp变量没有提前绑定固定类型,第一次赋值时推导为(string | number)[],第二次赋值后TS会自动将其类型收窄为string[],不会触发类型报错。
- 方案2:返回时加一次类型断言(不推荐,有损类型安全)
function test(input: (string | number)[]): string[] { input = input.map(x => x.toString()) return input as string[] }
该方案不需要额外声明变量,但如果在重赋值input和返回之间,有修改input元素的操作,类型断言会掩盖真实的类型错误,安全性远低于赋值给新变量的方案。
内容的提问来源于stack exchange,提问作者Matthijs Steen
相关产品推荐
相关产品推荐

