Cast Object To Interface In TypeScript
Answer :
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 = <IToDoDto> req.body; // or const toDo = req.body as IToDoDto; 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); Here's another way to force a type-cast even between incompatible types and interfaces where TS compiler normally complains:
export function forceCast<T>(input: any): T { // ... do runtime checks here // @ts-ignore <-- forces TS compiler to compile this as-is return input; } Then you can use it to force cast objects to a certain type:
import { forceCast } from './forceCast'; const randomObject: any = {}; const typedObject = forceCast<IToDoDto>(randomObject); Note that I left out the part you are supposed to do runtime checks before casting for the sake of reducing complexity. What I do in my project is compiling all my .d.ts interface files into JSON schemas and using ajv to validate in runtime.
If it helps anyone, I was having an issue where I wanted to treat an object as another type with a similar interface. I attempted the following:
Didn't pass linting
const x = new Obj(a as b); The linter was complaining that a was missing properties that existed on b. In other words, a had some properties and methods of b, but not all. To work around this, I followed VS Code's suggestion:
Passed linting and testing
const x = new Obj(a as unknown as b); Note that if your code attempts to call one of the properties that exists on type b that is not implemented on type a, you should realize a runtime fault.
Comments
Post a Comment