簡體   English   中英

如何在@input() 變量上使用類型斷言?

[英]How to use type assertion on @input() variable?

我創建了多個接口的聯合類型,這些接口通過 inheritance 共享一個共同的父級。 該聯合類型被傳遞給特定組件。 這些組件永遠只是子類型之一。 如何在子組件上聲明類型?

例子:

interface Common {
  a: string;
  b: string;
}

interface Child1 extends Common {
  c: string;
}

interface Child2 extends Common {
  d: string;
}

type Union = Child1 | Child2;

父組件有一個變量

data: Union;

並將其傳遞給子組件,如下所示:

<app-child1 [data]="data"></app-child1>
<app-child2 [data]="data"></app-child2>

子組件只會是其中一種類型,所以我應該能夠以某種方式斷言它:

@Input() data: Child1;

目前這將引發類型錯誤,聲稱 Child1 缺少屬性。

我試過這些@Input() data: Union as Child1; <app-child1 [data]="data as Child1">但那些只是打破。

我怎樣才能正確地斷言這一點?

您是否僅在子組件中嘗試過此操作

@Input() data: Union;

傳遞或調用子組件時不要傳遞類型

<app-child1 [data]="data as Child1"> // not this
<app-child1 [data]="data"> // pass only data 

隨時指出任何問題

// 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
    }
}

並在父母

<app-child1 [data]="data">

您可以轉換為任何:

<app-child1 [data]="$any(data)"></app-child1>
<app-child2 [data]="$any(data)"></app-child2>

或者像這樣轉換為預期的類型:

在您的父組件中:

asChildOne = (data: Union): Child1 => data as Child1;
asChildTwo = (data: Union): Child2 => data as Child2;

在父模板中:

<app-child1 [data]="asChildOne(data)"></app-child1>
<app-child2 [data]="asChildTwo(data)"></app-child2>

或者,如果您只想在類型確實是它需要的類型時渲染孩子,您可以做一些類型保護

在您的界面附近的某個地方:

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;
}

在您的父組件中:

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;

在父模板中:

<app-child1 *ngIf="isChildOne(data)" [data]="asChildOne(data)"></app-child1>
<app-child2 *ngIf="isChildTwo(data)" [data]="asChildTwo(data)"></app-child2>

你可以像這樣簡單地使用,

@Input() data: Child1 | Child2;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM