flyingbee
flyingbee

Reputation: 621

Typescript: How to check interface type

I have a method getUniqueId which accepts two kinds of interfaces below, which will return the uniqueId depending which interface type passed:

interface ReadOnlyInfo {
    itemId: string;
    ....
}

interface EditInfo {
    formId: number; 
    ....
}

function getUniqueId (info: ReadOnlyInfo | EditInfo) {
   if (info instanceof ReadOnlyInfo) {
       return info.itemId;
   }
   return info.formId;
}

I am wondering if this is a good practice to use instanceof here. My concern is that I might have many other methods similar to getUniqueId, which accept "ReadOnlyInfo | EditInfo" type as well, so I have to repeat "ReadOnlyInfo | EditInfo" everywhere.

Instead of doing that, I also tried using type:

type CommonInfo = | ReadOnlyInfo | EditInfo;

so, that I can save some code (just do CommondInfo), like below, but that way, I cannot tell which type CommonInfo is, instanceof no longer works and gives me compiler errors.

function getUniqueId (info: CommonInfo) {
     if (info instanceof ReadOnlyInfo) {
           return info.itemId;
       }
       return info.formId;   
}

So, I am wondering what would be the best practice to design interface/methods in this scenario. Thanks in advance!

Upvotes: 6

Views: 22874

Answers (2)

Ranjeet Thorat
Ranjeet Thorat

Reputation: 170

You could use pattern where you use some common internal property across the interfaces which you want to differentiate . Ex.

export default User;

interface ReadOnlyInfo {
  _kind: 'readonly';
  itemId: string;
  ....
}

interface EditInfo {
  _kind: 'edit';
  formId: number; 
  ....
}

function getUniqueId (info: ReadOnlyInfo | EditInfo) {
 if (info._kind === 'readonly') {
     return info.itemId;
 }
 return info.formId;
}

Upvotes: 1

Interfaces in Typescript just syntatic sugar for your ide. It is not possible to check interface types like in other languages. Knowing in C# for example.

But with type guard you can recognize which interface are in use.

interface ReadOnlyInfo {
    itemId: string;
    ....
}

interface EditInfo {
    formId: number; 
    ....
}

function getUniqueId (info: ReadOnlyInfo | EditInfo) {
    if (isReadOnlyInfo(info)) return info.itemId;
    if (isEditInfo(info)) return info.formId;
}

function isReadOnlyInfo(item: any): item is ReadOnlyInfo {
    return 'itemId' in item;
}

function isEditInfo(item: any): item is EditInfo {
    return 'formId' in item;
}

On this way you get a better ide support

Upvotes: 14

Related Questions