Check if variable belongs to custom type in Typescript

Viewed 19409

I'm trying to check whether a variable belongs to a certain type or not.

Code:

type GeneralType = SubTypeA | SubTypeB;
type SubTypeA = 'type1' | 'type2';
type SubTypeB = 'type3' | 'type4';

function someFunction(arg1: GeneralType) {
  if (arg1 instanceof SubTypeA) {
    // Do something
  }
  // Continue function
  return arg1;
}

Of course this code fails in line 6 because instanceof is not usable for types. Is there an alternative option I could use without needing to check explicitly every posible value for SubTypeA?

2 Answers

As mentioned in the comments, it seems there's no strightforward method to achieve this.

Finally, the most elegant way I found to do it is using Type Guards as follows:

type GeneralType = SubTypeA | SubTypeB;
type SubTypeA = 'type1' | 'type2';
type SubTypeB = 'type3' | 'type4';

function someFunction(arg1: GeneralType) {
  if (isSubTypeA(arg1)) {
    // Do something
  }
  // Continue function
}

function isSubTypeA(arg: GeneralType): arg is SubTypeA {
  return ['type1', 'type2'].some(element => element === arg);
}

A more detailed explanation can be found here.

Type guards are commonly used to discriminate unions. There are more ways this can be done:

  1. Use the switch statement.
  2. Use enums.

The switch statement

This method is easy but can become cumbersome if your unions are big.

function someFunction(arg1: GeneralType) {
  switch(arg1) {
      case 'type1':
      case 'type2':
        return /* */  
      default:
        /* ... */
  }
}

someFunction('type1');

Enums

The disadvantage here is that it doesn't work with string enums, only the regular ones.

enum SubTypeA {
    type1,
    type2,
}

enum SubTypeB {
    type3,
    type4,
}

type GeneralType = SubTypeA | SubTypeB;

function someFunction(arg1: GeneralType) {
    if (arg1 in SubTypeA) {
        /* ... */
    }
}

someFunction(SubTypeA.Type1);

As you can see, writing a type guard requires more work up front, but type guards don't have the limitations other methods have. In addition to that, they are just functions, so they can be reused. You made a good choice.

Related