簡體   English   中英

如何處理Duck類型的TypeType接口的聯合類型?

[英]How to handle duck-typed union types to TypeScript interfaces?

我是TypeScript的新手,仍在嘗試解決問題。

我有一系列構成時間表的事件。 他們看起來像這樣:

const timeline = [{
  type: 'payment',
  amount: '12.23 USD',
  when: '<iso timestamp>'
},{
  type: 'payment',
  amount: '12.23 USD',
  when: '<iso timestamp>'
},{
  type: 'refunded',
  amount: '2.00 USD',
  when: '<iso timestamp>'
},{
  type: 'payment',
  amount: '12.23 USD',
  when: '<iso timestamp>'
},{
  type: 'delinquent',
  when: '<iso timestamp>'
}]

因此,我已經將IEvent定義為聯合類型:

interface IPaymentEvent {
  amount: string,
  when: string
}

interface IRefundedEvent {
  amount: string,
  when: string
}

interface IDelinquentEvent {
  when: string
}

type IEvent = IPaymentEvent | IRefundedEvent | IDelinquentEvent

問題是我很困惑如何在代碼中使用此類型信息。 如何將該時間軸轉換為我剛剛定義的實際類型? 當我遍歷數組時如何解構聯合類型?

我的嘗試如下所示:

class PaymentEvent implements IPaymentEvent {}
class RefundedEvent implements IRefundedEvent {}
class DelinquentEvent implements IDelinquentEvent {}

const duckTypeMap = {
  payment: PaymentEvent,
  refunded: RefundedEvent,
  delinquent: DelinquentEvent
}

const typedTimeline = timeline.map(x => {
  return duckTypeMap[x.type](x)
})

console.log(typedTimeline)

但這不是很有效

我覺得這里必須有一種普遍的做法。 我也很感興趣是否有兩種方法可以做到這一點:(1)使用es6類和(2)不使用es6類。 對於后者,如果我們告訴它鴨子是如何鍵入JSON的,似乎類型系統應該能夠提供幫助。

你快到了。 要解決的幾件事:

  1. 為了創建類型的實例,您應該使用new關鍵字new duckTypeMap[x.type];
  2. 為了初始化此實例的字段,您應該創建復制構造函數或僅映射json對象(手動或使用某些庫)。 例如看這個答案。
  3. 如果您的類實現了該接口,則應聲明該接口的成員。 同樣不確定使用union類型會獲得什么。 為了具有多態數組,您可以只定義帶有when屬性的單個接口IEvent並在所有類中實現它。

像這樣:

interface IEvent {
    when: string
}

class PaymentEvent implements IEvent {
    public amount:string;
    public when:string;
}

const typedTimeline:IEvent[] = timeline.map(x => {
    let target = new duckTypeMap[x.type];
    for (const key in x) {
        target[key] = x[key];
    }
    return target;
});

要在迭代“類型化”數組時確定項目類型,可以使用instanceof運算符:

if(item instanceof RefundedEvent)

暫無
暫無

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

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