如何正确使用类型守卫

huangapple go评论59阅读模式
英文:

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;
}

huangapple
  • 本文由 发表于 2023年3月31日 16:20:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75896330.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定