angular - Angular Pipe 和 TypeScript 类型保护
问题描述
我在这里和这里读到了 typescript 中的类型保护。但我仍然得到编译器错误。
错误:(21, 14) TS2349: 无法调用其类型缺少调用签名的表达式。类型 '{ (callbackfn: (value: Foo, index: number, array: Foo...' 没有兼容的调用签名。
我有以下课程:
脚
export class Foo {
expired: boolean;
}
巴茨
export class Bar {
foo: Foo;
}
MyPipe.ts
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'myPipe'
})
export class MyPipe implements PipeTransform {
transform(items: Foo[] | Bar[], isExpired: Boolean): Foo[] | Bar[] {
if (!items) {
return items;
}
if (items[0] instanceof Foo) {
return items.filter((foo: Foo) => {
return foo.expired == isExpired;
});
} else {
return items.filter((bar: Bar) => {
return bar.foo.expired == isExpired;
});
}
}
}
问题是,如何使用 typescript 在我的角管道中同时实现对参数“items”的联合绑定和类型保护的使用?
解决方案
Typescript 通常不会根据字段的类型来缩小变量的类型(区分联合除外)。更具体地说,打字稿不会根据数组索引进行缩小(这是一个已知的限制)
您可以做的最简单的事情是使用类型断言,或更优雅的解决方案,自定义类型保护:
class Foo { private x: string; expired: boolean }
class Bar { private x: string; foo: Foo }
function isArrayOf<T>(ctor: new (...args: any[]) => T, arr: any): arr is T[] {
return arr[0] instanceof ctor
}
export class MyPipe {
transform(items: Foo[] | Bar[], isExpired: Boolean): Foo[] | Bar[] {
if (!items) {
return items;
}
if (isArrayOf(Foo, items) {
return items.filter((foo: Foo) => {
return foo.expired == isExpired;
});
} else {
return items.filter((bar: Bar) => {
return bar.foo.expired == isExpired;
});
}
}
}
推荐阅读
- php - 如何在数组的 3 个级别中搜索?
- rstudio - 最近的文件历史 R
- html - 无法应用 CSS,可能是因为 Bootstrap
- reactjs - 动态改变颜色 ReactJS
- ios - 如何在 UIActionSheet 上放置图像?
- python - NoSuchElementException:消息:没有这样的元素:无法找到元素:{“method”:“name”,“selector”:“username”}同时向用户名发送文本
- python - 检测由空白像素分隔的轮廓
- chartjs-2.6.0 - 在chartjs折线图中添加间隙
- flutter - Gridview 在颤动中不可见
- angular - 角度对话框未作为模式窗口打开