Typescript/Javascript使用filter方法时如何对临时变量做类型检查
TypeScript 中 filter 回调内实现 Foo 类型检查的正确方式
你尝试的 filter({foo:Foo} => foo.id === bar.id) 写法不生效,是因为该语法属于 JavaScript 原生的解构重命名语法,会被解析为将参数对象的 foo 属性赋值给名为 Foo 的变量,和 TypeScript 类型注解没有任何关联。
以下是两种适用场景的正确实现方案:
场景1:仅需要编译时类型提示(无运行时校验)
如果可以确保 getSomeFromFunction 数组的元素仅可能是 Foo 类型,只需要给箭头函数参数加上正确的类型注解即可:
const getSomeVariableFromAFunction = getSomeFromFunction .filter((foo: Foo) => foo.id === bar.id) .map(foo => foo.virtenv) .sort();
注意:该写法仅做编译时的类型检查,运行时不会校验元素是否真的符合 Foo 类型规范。
场景2:需要编译时类型收窄+运行时类型校验
如果数组元素可能存在非 Foo 类型的项,需要先实现类型守卫函数,再结合 filter 的类型谓词实现类型校验:
- 首先定义类型守卫,用于运行时判断变量是否符合 Foo 类型结构:
// 自定义判断逻辑,覆盖 Foo 类型所有必填属性的校验规则 function isFoo(target: unknown): target is Foo { return typeof target === 'object' && target !== null && 'id' in target && 'virtenv' in target // 可补充其他 Foo 类型特有属性的校验逻辑 }
- 在 filter 回调中使用类型守卫,同时实现类型校验和过滤逻辑:
const getSomeVariableFromAFunction = getSomeFromFunction .filter((item): item is Foo => isFoo(item) && item.id === bar.id) .map(foo => foo.virtenv) .sort();
该写法既会在运行时过滤掉非 Foo 类型的元素,也会让 TypeScript 自动将 filter 返回的数组元素类型收窄为 Foo,后续 map 调用不需要再额外加类型注解。
内容的提问来源于stack exchange,提问作者TypeScriptProgrammer1234
相关产品推荐
相关产品推荐

