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(readonlyrole:IReader|IWriter){};interfaceIReader{interfaceIWriter{readonlypermissions:Array<string>functionguardAccess(user:User){// Oh no it is not working 😱// Error TS2693if(user.roleinstanceofIReader){thrownewAccessDeniedException();functionguardAccess(user:User){// ✔️ no errorif(user.role.name==="reader"){thrownewAccessDeniedException();
// lets create a user with role readerconstuser=getUser();if(user.role.name==="reader"){user.role.name;user.role.permissions;// 🛑 errorelseif(user.role.name==='writer'){user.role.name;user.role.permissions;// ✔️ no errorEnter fullscreen modeExit fullscreen mode
if(user.role.name==="editor"){// 🛑 Error: TS 2367This condition will always return 'false'// since the types '"reader" | "writer"' and '"editor"' // have no overlap.Enter fullscreen modeExit fullscreen mode
That is it. Now we can have similar behavior to the instance of the interface in TypeScript.
This article is not about specific domain but about how to check interface at runtime.
And proposed solution works if you don’t need polymorphism.
For example you have role reader that can only read and role writer with claims for what it can write.
Once unpublished, all posts by worldpwn will become hidden and only accessible to themselves.
If worldpwn is not suspended, they can still re-publish their posts from their dashboard.