簡體   English   中英

class 轉換可區分聯合

[英]class transformation of discriminated unions

我玩過routing-controllers ,它具有內置的類轉換器功能。 我嘗試構建一個界面,我可以在其中基於location idlocation coordinate執行搜索查詢。 所以我打算使用一個有區別的聯合作為一個身體參數並且不能讓它工作。 (參見最后一個控制台 output 我所說的“不工作”是什么意思)

舉個例子:

interface LocationCoordinates {
    type: 'coordinate'
    longitude: number
    latitude: number
}

interface LocationId {
    type: 'id'
    id: number
}

class LocationRadius {
    data: LocationCoordinates | LocationId
    searchRadiusInKm: number
}

// raw input for LocationCoordinates
const rawLocationCoordinates = {
    data: {
        longitude: 22,
        latitude: 33
    },
    searchRadiusInKm: 30
}


// raw input for LocationId
const rawLocationId = {
    data: {
        id: 1
    },
    searchRadiusInKm: 30
}
// transfrom both raw inputs
const realLocationCoordinates = plainToClass(LocationRadius, rawLocationCoordinates);
const realLocationId = plainToClass(LocationRadius, rawLocationId);


console.log({
    coordinateType: realLocationCoordinates.data.type, // expect 'coordinate' but got 'undefinded'
    idType: realLocationId.data.type // expect 'id' but got 'undefinded'
});

有沒有辦法做到這一點?

您可以這樣做,但您需要進行一些更改:

  1. LocationIdLocationCoordinates應該是類
  2. 您應該將@Type裝飾器添加到輸入屬性。 這允許class-transformer器根據特定的鑒別器參數處理反序列化
class LocationRadius {
 @Type(() => Object, {
     keepDiscriminatorProperty: true,
     discriminator: {
         property: "type",
         subTypes: [
             { value: LocationCoordinates, name: "coordinate" },
             { value: LocationId, name: "id" }
         ]
     }
 })
 data: LocationCoordinates | LocationId
 searchRadiusInKm: number
}
  1. 您應該在輸入中添加一個type屬性,以允許甚至 TS 區分聯合:
 // raw input for LocationCoordinates
const rawLocationCoordinates = {
   data: {
       type: "coordinate",
       longitude: 22,
       latitude: 33
   },
   searchRadiusInKm: 30
}

你可以在我設置的這個StackBlitz 項目中看到結果

暫無
暫無

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

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