我有一个 angular 应用程序
"angularCompilerOptions": {
"strictInjectionParameters": true,
"fullTemplateTypeCheck": true,
"strictTemplates": true
}
所以每个输入/输出都没有经过类型检查。
它适用于大多数应用程序,但我有一些应用程序输入,例如(这里我显示选择,但我也有一个简单的 app-input
工作相同):
.html
<app-select
[useSearch]="true"
[formControlName]="'country'"
(valueChange)="setSelectedCountry($event)" <=== $event is of type unknown
>
<app-option
*ngFor="let country of locations$ | async"
[name]="'COUNTRIES.' + country.code | translate"
[value]="country.code" <=== this is of type Country
></app-option>
</app-select>
.ts
setSelectedCountry(code: Country) {
this.store.dispatch(loadLocationRequest({ payload: { code } }));
this.selectedLocation$ = this.store.pipe(select(getLocationByCode(), { code }));
}
在上面,因为我使用我的 app-select
作为具有各种值的多重选择器,所以它是类型:
@Input()
get value(): unknown | unknown[] {
return this.pValue;
}
set value(newValue: unknown | unknown[]) {
if (newValue !== this.pValue) {
this.pValue = newValue;
this.writeValue(newValue);
}
}
现在,我看到了 2 个解决方案,
[(value)]="country"
,我创建了一个方法来检查所有使用 select 的组件:但我只想对这些情况做一些更简单的事情。
是否可以通过输入或其他方式将泛型类型传递给组件,以便它返回我传递的泛型类型?
喜欢(例如:<app-select<string>>
)
是否可以制作一个将 a 转换为通用值的管道?无需为每种类型制作管道? string
number
等等...?
是否可以忽略某些检查?
答案 0 :(得分:0)
所以,我尝试了多种方法,并且采用了一种hacky 方式,我真的不推荐,除非在某些特殊情况下(有点像 $any())。
正确的方法是:
每个未知类型都有一个管道,这样你就可以在类型内部做一些类型检查来排除
import { Pipe, PipeTransform } from '@angular/core'
import { Gender } from '@app/__generated__/globalTypes'
@Pipe({
name: 'toAnimal',
pure: true,
})
export class ToAnimalPipe implements PipeTransform {
transform(value: unknown): Animal {
return typeof value === "string" && Object.keys(Animal).includes(value) ?
value as Animal :
Animal.DOG // Default value just use anything you want.
}
}
骇人听闻的方法:
我做了以下简单的管道:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'toType',
pure: true,
})
export class ToTypePipe implements PipeTransform {
transform<T>(value: unknown, _: T): T {
return value as T;
}
}
你可以这样称呼它
value | toType: Animal.DOG
value 可以是 Animal
的任何值,但我们只是将 is 转换为值之一,因此编译器认为可以使用它并且不会抱怨。
这是不安全的,并且有点消除严格模式的目的。
但是,它允许做一些解决方法并使一些非常简单的演员变得容易。就像在这种情况下:
<table [dataSource]="animals"> <=== Array<Animal>
<ng-container [cdkColumnDef]="columns.name.def">
<td class="align-items-center p-4 w-80" cdk-cell *cdkCellDef="let element">
*cdkCellDef="let element"
这是一个 Animal
但角度模板不允许我们有正确的输入,所以在这种情况下 let element | typeOf: Animal.DOG
应该是完全安全的