[英]How to use type assertion on @input() variable?
I have created a union type of several interfaces that share a common parent through inheritance.我创建了多个接口的联合类型,这些接口通过 inheritance 共享一个共同的父级。 That union type is passed on to specific components.
该联合类型被传递给特定组件。 Those components will only ever be one of the child types.
这些组件永远只是子类型之一。 How can I assert the type on the child component?
如何在子组件上声明类型?
Example:例子:
interface Common {
a: string;
b: string;
}
interface Child1 extends Common {
c: string;
}
interface Child2 extends Common {
d: string;
}
type Union = Child1 | Child2;
The parent component has a variable父组件有一个变量
data: Union;
and passes it to child components like so:并将其传递给子组件,如下所示:
<app-child1 [data]="data"></app-child1>
<app-child2 [data]="data"></app-child2>
The child component will only ever be one of those types so I should be able to assert it somehow:子组件只会是其中一种类型,所以我应该能够以某种方式断言它:
@Input() data: Child1;
Currently this will throw a type error claiming Child1 is missing properties.目前这将引发类型错误,声称 Child1 缺少属性。
I've tried these @Input() data: Union as Child1;
我试过这些
@Input() data: Union as Child1;
and <app-child1 [data]="data as Child1">
but those just break.和
<app-child1 [data]="data as Child1">
但那些只是打破。
How can I assert this correctly?我怎样才能正确地断言这一点?
Have you tried this only in child component您是否仅在子组件中尝试过此操作
@Input() data: Union;
Do not pass type while passing or calling child component传递或调用子组件时不要传递类型
<app-child1 [data]="data as Child1"> // not this
<app-child1 [data]="data"> // pass only data
Feel free to point out any problems随时指出任何问题
// You can use this setter pattern, I use this
class ChildComponent {
data: Child1;
@Input() set( d: Union ) {
data = d as unknown as Child1;
// One problem is that you can slip the 'd' prop in the UNION type object from the parent but you can always use if statement to remedy that
}
}
and in Parent并在父母
<app-child1 [data]="data">
You could just cast to any:您可以转换为任何:
<app-child1 [data]="$any(data)"></app-child1>
<app-child2 [data]="$any(data)"></app-child2>
Or cast to the expected type like this:或者像这样转换为预期的类型:
In your parent component:在您的父组件中:
asChildOne = (data: Union): Child1 => data as Child1;
asChildTwo = (data: Union): Child2 => data as Child2;
In the parent template:在父模板中:
<app-child1 [data]="asChildOne(data)"></app-child1>
<app-child2 [data]="asChildTwo(data)"></app-child2>
Or if you want to render the child only if the type is really the type it needs, you can do some type guards :或者,如果您只想在类型确实是它需要的类型时渲染孩子,您可以做一些类型保护:
Somewhere near your interfaces:在您的界面附近的某个地方:
export function isCommon(obj: any): obj is Common {
return obj && 'a' in obj && 'b' in obj;
}
export function isChild1(obj: any): obj is Child1 {
return isCommon(obj) && 'c' in obj;
}
export function isChild2(obj: any): obj is Child2 {
return isCommon(obj) && 'd' in obj;
}
In your parent component:在您的父组件中:
isChildOne = (data: Union): data is Child1 => isChild1(data)
isChildTwo = (data: Union): data is Child2 => isChild2(data)
asChildOne = (data: Union): Child1 => data as Child1;
asChildTwo = (data: Union): Child2 => data as Child2;
In the parent template:在父模板中:
<app-child1 *ngIf="isChildOne(data)" [data]="asChildOne(data)"></app-child1>
<app-child2 *ngIf="isChildTwo(data)" [data]="asChildTwo(data)"></app-child2>
You can simply use like this,你可以像这样简单地使用,
@Input() data: Child1 | Child2;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.