Search code examples
angulartypescript

How do you call a variable with two types in Angular/Typescript?


Let's say I have this variable with the typing as below:

test?: boolean | { [key in TestEnum ]: boolean };

And I set this test variable inside a constant where it can be be just the boolean value or the mapping to the enum one. Please see example below:

SAMPLE VALUES SET IN A CONSTANT OBJECT

export const TEST_1 {
  name: "Mark",
  test: {
    [TestEnum.Value1]: false,
    [TestEnum.Value1]: true,
    [TestEnum.Value1]: true,
    [TestEnum.Value1]: true
  }

  }
};

export const TEST_2 {
  name: "Mark",
  test: true
  }
};

How do I call this test variable in my component as it can either be just test or test[TestEnum.Value2]


Solution

  • Like described in the handbook, you can perform type narrowing with TypeScript using the typeof operator. In you case, you can check whether the value is a boolean or an object:

    export interface MyInterface {
        name: string;
        test?: boolean | { [key in TestEnum ]: boolean };
    }
    
    export const TEST_1: MyInterface = {
      name: "Mark",
      test: {
        [TestEnum.Value1]: false,
        [TestEnum.Value2]: true,
        [TestEnum.Value3]: true,
        [TestEnum.Value4]: true
      }
    };
    
    export const TEST_2: MyInterface = {
      name: "Mark",
      test: true
    };
    
    function process(value: MyInterface) {
        if (typeof value.test === 'boolean') {
            console.log(value.test) // we know that this is a boolean;
        } else if (typeof value.test === 'object') {
            console.log(value.test[TestEnum.Value2]); // we know that this is an object so we can access the properties
        }
    }
    

    Also check out this demo in TypeScript playground, there I also added a try to access test[TestEnum.Value2] outside the typeof guard, which leads to an error.