我试图在我的代码中使用快速(使用正文解析器中间件)的请求体转换到接口,但它无法正常工作。可以这样做吗?
这是我的界面:
export interface IToDoDto {
description: string;
status: boolean;
};
这是我试图进行演员表的代码:
@Post()
addToDo(@Response() res, @Request() req) {
const toDo: IToDoDto = <IToDoDto> req.body;
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++;
}
我可以传递任何参数,这样可以正常工作。我已经读过在TypeScript中不存在转换但是类型断言,所以它只会告诉编译器一个对象的类型是x,所以......我错了吗?这样做的方法是什么?感谢。
答案 0 :(得分:54)
javascript中没有强制转换,因此如果“强制转换失败”,则无法抛出 打字稿supports casting但这只是编译时间,你可以这样做:
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);
答案 1 :(得分:4)
这是在不兼容的类型和TS编译器通常抱怨的接口之间强制类型转换的另一种方法:
export function forceCast<T>(input: any): T {
// ... do runtime checks here
// @ts-ignore <-- forces TS compiler to compile this as-is
return input;
}
然后您可以使用它来强制将对象强制转换为特定类型:
import { forceCast } from './forceCast';
const randomObject: any = {};
const typedObject = forceCast<IToDoDto>(randomObject);
请注意,为了减少复杂性,我在铸造前省略了您应该进行运行时检查的部分。我在项目中所做的工作是将我所有的.d.ts
接口文件编译为JSON模式,并使用ajv
在运行时进行验证。
答案 2 :(得分:0)
如果它可以帮助任何人,那么我有一个问题,我想将一个对象视为具有相似接口的另一种类型。我尝试了以下操作:
没有通过棉绒
const x = new Obj(a as b);
短毛绒抱怨a
缺少b
上存在的属性。换句话说,a
具有b
的某些属性和方法,但不是全部。要解决此问题,我遵循了VS Code的建议:
通过了棉签和测试
const x = new Obj(a as unknown as b);
请注意,如果您的代码尝试调用类型b
上未实现的类型a
上存在的属性之一,则应意识到运行时错误。