TypeScript中能否将成员函数类型谓词用作filter()的断言?
能否将成员函数类型谓词用作filter()的谓词?
当然可以,不过你当前的写法需要手动指定filter的泛型参数,其实有更简洁的方式让TypeScript自动推导类型,避免冗余注解。
问题分析
你的isDisplayable()方法本身已经是一个类型谓词函数,但当你把它包裹在箭头函数里作为filter的回调时,TypeScript无法自动识别这个箭头函数的返回值是类型谓词——它只会把箭头函数当成普通的返回布尔值的函数,所以需要手动指定泛型<DisplayableThing>来修正类型。
解决方案1:直接传递成员函数引用
最简单的方式是直接把isDisplayable方法作为filter的回调,不需要额外的箭头函数包裹:
class Thing { name?: string; color?: string; notes?: string; constructor(public id: string) {} isDisplayable(): this is DisplayableThing { return this.name !== undefined && this.color !== undefined; } } interface DisplayableThing extends Thing { name: string; color: string; } const things: Thing[] = []; // 直接传递成员函数,TypeScript会自动推导类型 const displayableThings = things.filter(Thing.prototype.isDisplayable); // displayableThings 的类型自动是 DisplayableThing[]
这里Thing.prototype.isDisplayable的类型是(this: Thing) => this is DisplayableThing,filter会自动为每个数组元素绑定正确的this上下文,TypeScript能识别这个方法的类型谓词,从而自动推断筛选后的数组类型。
解决方案2:显式标注箭头函数的类型谓词
如果需要在箭头函数里添加额外逻辑(比如结合其他条件),可以给箭头函数显式标注返回类型为类型谓词:
const displayableThings = things.filter((thing): thing is DisplayableThing => { // 可以在这里添加额外判断逻辑 return thing.isDisplayable(); });
或者把这个回调抽成复用的函数,避免重复标注:
const isThingDisplayable = (thing: Thing): thing is DisplayableThing => thing.isDisplayable(); const displayableThings = things.filter(isThingDisplayable);
适配你的业务场景
结合你通过EventSource逐步更新Thing属性的场景,以上两种方式都能确保只有同时拥有name和color的实例被筛选为DisplayableThing,不需要手动指定泛型参数,完全由TypeScript自动推导类型,符合你避免冗余注解的需求。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

