Cast object to interface in TypeScript
casting, interface, object, typescript
Solution
There's no casting in javascript, so you cannot throw if "casting fails". Typescript supports casting but that's only for compilation time, and you can do it like this:
const toDo = req.body as IToDoDto;
// or
const toDo = <IToDoDto> req.body; // deprecated
You can check at runtime if the value is valid and if not throw an error, i.e.:
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();
}
Edit
As @huyz pointed out, there's no need for the type assertion because `isToDoDto` is a type guard, so this should be enough:
if (!isToDoDto(req.body)) {
throw new Error("invalid request");
}
this.toDoService.addToDo(req.body);
Problem
I'm trying to make a cast in my code from the body of a request in express (using body-parser middleware) to an interface, but it's not enforcing type safety. This is my interface: ``` export interface IToDoDto { description: string; status: boolean; }; ``` This is the code where I'm trying to do the cast: ``` @Post() addToDo(@Response() res, @Request() req) { const toDo: IToDoDto = <IToDoDto> req.body; // <<< cast here this.toDoService.addToDo(toDo); return res.status(HttpStatus.CREATED).end(); } ``` And finally, the service method that's being called: ``` public addToDo(toDo: IToDoDto): void { toDo.id = this.idCounter; this.todos.push(toDo); this.idCounter++; } ``` I can pass whatever arguments, even ones that don't come close to matching the interface definition, and this code will work fine. I would expect, if the cast from response body to interface is not possible, that an exception would be thrown at runtime like Java or C#. I have read that in TypeScript casting doesn't exist, only Type Assertion, so it will only tell the compiler that an object is of type `x`, so... Am I wrong? What's the right way to enforce and ensure type safety?