簡體   English   中英

無法訪問聯合類型(TypeScript)中的參數

[英]Unable to access parameters from union types (TypeScript)

為什么無法訪問像這樣的聯合類型中的屬性:

export interface ICondition {
  field: string
  operator: string
  value: string
}

export interface IConditionGroup {
  conditions: ICondition[]
  group_operator: string
}

function foo(item: ICondition | IConditionGroup) {
  if(typeof item.conditions === "undefined") { // does not work
    let field = item.field; // does not work
    ///.. do something 
  } else {
    let conditions = item.conditions; // does not work
    /// .. do something else
  }
}

我得到這些錯誤:

error TS2339: Property 'conditions' does not exist on type 'ICondition | IConditionGroup'.
error TS2339: Property 'conditions' does not exist on type 'ICondition | IConditionGroup'.
error TS2339: Property 'field' does not exist on type 'ICondition | IConditionGroup'.

但是我必須強制轉換類型才能使其正常工作-像這樣:

function foo2(inputItem: ICondition | IConditionGroup) {
  if(typeof (<IConditionGroup>inputItem).conditions === "undefined") {
    let item= (<ICondition>inputItem);
    let field = item.field;
    ///.. do something 
  } else {
    let item= (<IConditionGroup>inputItem);
    let conditions = item.conditions;
    /// .. do something else
  }
}

我知道類型信息在JS中丟失了,為什么我必須在TS中顯式轉換它?

Typescript使用Type Guards處理此問題,通常很簡單:

if (typeof item === "string") { ... } else { ... }

要么

if (item instanceof MyClass) { ... } else { ... }

但是對於您來說,由於您無法使用接口,因此您需要創建自己的用戶定義類型保護

function isConditionGroup(item: ICondition | IConditionGroup): item is IConditionGroup {
    return (item as IConditionGroup).conditions !== undefined;
}

function foo(item: ICondition | IConditionGroup) {
    if (isConditionGroup(item)) {
        let conditions = item.conditions;
        // do something
    } else {
        let field = item.field;
        // do something else
    }
}

操場上的代碼

您也可以在沒有類型保護的情況下執行此操作:

function foo(item: ICondition | IConditionGroup) {
    if ((item as IConditionGroup).conditions !== undefined) {
        let conditions = (item as IConditionGroup).conditions;
        // do something
    } else {
        let field = (item as ICondition).field;
        // do something else
    }
}

但這是冗長的方式,因為您需要輸入3次而不是一次的斷言item

暫無
暫無

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

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