This website collects cookies to deliver better user experience
TypeScript 'instanceof' interface is it possible?
TypeScript 'instanceof' interface is it possible?
I really like the power of interfaces in TypeScript and its duck typing. But what really bothers me is that I cannot check whether is something an instance of interface.
For example, we have decided to build a role model for the user class. User class will have different roles and based on role type it either has permissions or not. And we decided to describe roles as interfaces.
So I want to have code like this:
classUser{constructor(readonly role:IReader|IWriter){};}interfaceIReader{}interfaceIWriter{readonly permissions:Array<string>}functionguardAccess(user:User){// Oh no it is not working 😱// Error TS2693if(user.roleinstanceofIReader){thrownewAccessDeniedException();}}
But in TypeScript, it won't work. Because types do not exist in runtime. There is no such thing as an interface in JavaScript.
Ok, so how can we fix this?
We can use string literal types in TypeScript to identify the interface. Let's update our code:
classUser{constructor(readonly role:IReader|IWriter){};}interfaceIReader{readonly name:"reader",}interfaceIWriter{readonly name:"writer"readonly permissions:Array<any>}functionguardAccess(user:User){// ✔️ no errorif(user.role.name==="reader"){thrownewAccessDeniedException();}}
It allows us to get data that is available only in a certain interface.
// lets create a user with role readerconst user =getUser();if(user.role.name==="reader"){ user.role.name; user.role.permissions;// 🛑 error}elseif(user.role.name==='writer'){ user.role.name; user.role.permissions;// ✔️ no error}
Also it TypeScript will help us to control the values of the role's name.
if(user.role.name==="editor"){// 🛑 Error: TS 2367This condition will always return 'false'// since the types '"reader" | "writer"' and '"editor"' // have no overlap.}
That is it. Now we can have similar behavior to the instance of the interface in TypeScript.