为什么TypeScript调用Array.prototype.filter时会丢失已推断的类型?
问题原因解释
这是TypeScript上下文类型传导的正常特性,核心逻辑如下:
- TypeScript进行类型推断时,会优先计算等号右侧表达式的类型,再校验是否匹配左侧变量的类型注解。
- 不加
.filter()时,等号右侧是直接的数组字面量,支持上下文类型推断:TS会用左侧声明的Item[]约束右侧数组的元素类型,数组内的对象会被自动推断为Item类型,不会把id的类型拓宽为普通string,因此类型兼容。 - 加上
.filter()之后,右侧表达式变成了「数组字面量调用filter方法」的链式结构,上下文类型无法传导到最内层的数组字面量上。这时候TS会自主推断数组字面量的类型:认为数组元素是{ id: string }类型,.filter()返回值和原数组类型一致,也是{ id: string }[],该类型无法赋值给标注了Item[]的变量(普通string不能赋值给ItemIds枚举类型),因此抛出错误。
解决方案
有三种常用的修复方式:
- 方案1:给内层数组字面量加类型断言,手动指定数组类型
const items: Item[] = ([ { id: 'foo' }, { id: 'bar' } ] as Item[]).filter((item) => true)
- 方案2:给
filter方法显式传入泛型参数,指定过滤后的返回类型
const items: Item[] = [ { id: 'foo' }, { id: 'bar' } ].filter<Item>((item) => true)
- 方案3:拆分链式调用,先声明数组变量再调用filter,让上下文类型正常生效
const rawItems: Item[] = [ { id: 'foo' }, { id: 'bar' } ] const items = rawItems.filter((item) => true)
内容的提问来源于stack exchange,提问作者Jason Lee
相关产品推荐
相关产品推荐

