class歧视工会改造
class transformation of discriminated unions
我玩过 routing-controllers
,它是 build-in class-transformer 能力。我试图构建一个界面,我可以在其中执行基于 location id
或 location coordinate
的搜索查询。因此,我打算将 discriminated union 用作 body 参数,但无法使其正常工作。 (请参阅最后一个控制台输出 'not working' 的意思)
举个例子:
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'
});
有办法实现吗?
你可以这样做,但你需要做一些改变:
LocationId
和 LocationCoordinates
应该是 类
- 您应该向输入 属性 添加一个
@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
}
- 您应该在您的输入中添加一个
type
属性,以允许甚至 TS 区分并集:
// raw input for LocationCoordinates
const rawLocationCoordinates = {
data: {
type: "coordinate",
longitude: 22,
latitude: 33
},
searchRadiusInKm: 30
}
你可以在这个StackBlitz project看到结果我设置了
我玩过 routing-controllers
,它是 build-in class-transformer 能力。我试图构建一个界面,我可以在其中执行基于 location id
或 location coordinate
的搜索查询。因此,我打算将 discriminated union 用作 body 参数,但无法使其正常工作。 (请参阅最后一个控制台输出 'not working' 的意思)
举个例子:
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'
});
有办法实现吗?
你可以这样做,但你需要做一些改变:
LocationId
和LocationCoordinates
应该是 类- 您应该向输入 属性 添加一个
@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
}
- 您应该在您的输入中添加一个
type
属性,以允许甚至 TS 区分并集:
// raw input for LocationCoordinates
const rawLocationCoordinates = {
data: {
type: "coordinate",
longitude: 22,
latitude: 33
},
searchRadiusInKm: 30
}
你可以在这个StackBlitz project看到结果我设置了