Приведение объекта к интерфейсу в TypeScript
Я пытаюсь сделать приведение в моем коде из тела запроса в express (используя промежуточное ПО body-parser) к интерфейсу, но он не работает. Это возможно сделать?
Это мой интерфейс:
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, поэтому... Я ошибаюсь? И как это сделать? Спасибо.
2 ответов
в 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();
}
вот еще один способ заставить тип-cast даже между несовместимыми типами и интерфейсами, где компилятор 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
чтобы проверить в во время выполнения.