将对象转换为 TypeScript 中的接口

新手上路,请多包涵

我正在尝试在我的代码中从 express 中的请求主体(使用主体解析器中间件)到接口进行强制转换,但这并没有强制执行类型安全。

这是我的界面:

 export interface IToDoDto {
  description: string;
  status: boolean;
};

这是我试图做演员的代码:

 @Post()
addToDo(@Response() res, @Request() req) {
  const toDo: IToDoDto = <IToDoDto> req.body; // <<< cast here
  this.toDoService.addToDo(toDo);
  return res.status(HttpStatus.CREATED).end();
}

最后,被调用的服务方法:

 public addToDo(toDo: IToDoDto): void {
  toDo.id = this.idCounter;
  this.todos.push(toDo);
  this.idCounter++;
}

我可以传递任何参数, 甚至是那些与接口定义不匹配的 参数,并且这段代码可以正常工作。 我希望,如果从响应主体到接口的转换是不可能的,那么在运行时会抛出一个异常,如 Java 或 C#。

我读过 TypeScript 强制转换不存在,只有类型断言,所以它只会告诉编译器一个对象的类型是 x ,所以……我错了吗?执行和确保类型安全的正确方法是什么?

原文由 Elias Garcia 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 763
1 个回答

javascript 中没有强制转换,所以如果“强制转换失败”,你不能抛出。

Typescript 支持强制转换,但这仅适用于编译时间,您可以这样做:

 const toDo = <IToDoDto> req.body;
// or
const toDo = req.body as IToDoDto;

您可以在运行时检查该值是否有效,如果没有抛出错误,即:

 function isToDoDto(obj: any): obj is IToDoDto {
    return typeof obj.description === "string" && typeof obj.status === "boolean";
}

@Post()
addToDo(@Response() res, @Request() req) {
    if (!isToDoDto(req.body)) {
        throw new Error("invalid request");
    }

    const toDo = req.body as IToDoDto;
    this.toDoService.addToDo(toDo);
    return res.status(HttpStatus.CREATED).end();
}


编辑

正如@huyz 指出的那样,不需要类型断言,因为 isToDoDto 是类型保护,所以这应该足够了:

 if (!isToDoDto(req.body)) {
    throw new Error("invalid request");
}

this.toDoService.addToDo(req.body);

原文由 Nitzan Tomer 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进