英文:
How to use type-guard properly
问题
我尝试使用用户自定义类型保护,但不成功。也许有人可以告诉我如何应用我试图在这里实现的逻辑。
我有两个事件,DTO(数据传输对象)分别定义,然后我有一个包装器。
enum MyEvent {
Push = 'push',
Forward = 'forward',
}
class ForwardDTO {
email!: string;
subscriptionID!: string;
}
class PushDTO {
email!: string;
}
class EmitDTO {
payload!: ForwardDTO | PushDTO;
type!: MyEvent;
}
// 用法,我将这个JSON转换为类实例,使用class-transformer,但这里不显示它,以保持简单
const dto: EmitDTO = JSON.parse('{"payload: {"email": "my@email.com", "subID": "aabbcc"}", "type": "forward"}');
if (dto.type === MyEvent.Forward) {
// 显然下面的行不起作用,我需要进行类型转换
// const push = dto.payload.subID;
const push = (dto.payload as ForwardDTO).subID; // 这样可以,但是否可以不使用它?
}
我的目标是使用一个if
语句来获取正确的类型,当我得到EmitDTO
时。这是可能的吗?
基本上,我试图在不进行类型转换的情况下获取正确的类型。
我尝试过这种方式
class EmitDTO {
payload!: ForwardDTO | PushDTO;
type!: MyEvent;
isForward(): this.payload is ForwardDTO {
return this.type === MyEvent.Forward;
}
}
但那是错误的,显然,类型保护不能这样使用。
英文:
I was trying to use user-defined type guard unsuccessfully. And maybe someone can tell me how can I apply the logic I'm trying to achieve here.
I have two events and DTOs are defined accordingly, then I have one wrapper around it.
enum MyEvent {
Push = 'push',
Forward = 'forward',
}
class ForwardDTO {
email!: string;
subscriptionID!: string;
}
class PushDTO {
email!: string;
}
class EmitDTO {
payload!: ForwardDTO | PushDTO;
type!: MyEvent;
}
// Usage, I do convert this JSON into class instance with class-transformer but not showing it here to keep it simple
const dto: EmitDTO = JSON.parse('{"payload: {"email": "my@email.com", "subID": "aabbcc"}", "type": "forward"}');
if (dto.type === MyEvent.Forward) {
// Obviously not working the line below, I need to typecast
// const push = dto.payload.subID;
const push = (dto.payload as ForwardDTO).subID; // This works, but can we do without it?
}
My goal is when I get EmitDTO
with one if
statement to get the correct type. Is this even possible?
Basically, I'm trying to get the correct type without type-casting
I tried this way
class EmitDTO {
payload!: ForwardDTO | PushDTO;
type!: MyEvent;
isForward(): this.payload is ForwardDTO {
return this.type === MyEvent.Forward;
}
}
But that is wrong, and apparently, type guard cannot be used this way.
答案1
得分: 1
你可以将类型守卫的签名修改为:
isForward(): this is { payload: ForwardDTO }
然后就不需要显式类型转换了:
if (dto.isForward()) {
const push = dto.payload.subID;
}
英文:
You can amend that type guard signature to:
isForward(): this is { payload: ForwardDTO }
Then there is no explicit cast required:
if (dto.isForward()) {
const push = dto.payload.subID;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论