Home > other >  TypeScript determine if variable of type A or B
TypeScript determine if variable of type A or B

Time:01-20

Let's assume I have the following types:

type A = "foo" | "bar"
type B = "abc" | "def"

let x: A | B = "foo"

Right now, as far as I understand, x is of type A | B,

but actually, it has been assigned to be only of type A, right?

How can I find out that x uses an allowed value of type A without using code like

if(x === "foo" || x === "bar") {
    console.log("x is of type A")
}

CodePudding user response:

Because TypeScript is a static type-checker, it only operates at compile time. And because you've informed the compiler that x is of type A | B, then you also need to inform the compiler that (if a certain condition is true), then x can only be of type A. Therefore, the direct answer to your question is "it's not possible to narrow a type without using a conditional check of some sort".

A good reference for further exploration is the handbook section on type narrowing.

CodePudding user response:

TS already knows

type A = '1';
type B = 2;

const x: A | B = '1';

x.repeat(2); // No error

CodePudding user response:

let x: A | B = "foo"

Right now, as far as I understand, x is of type A | B, but actually, it has been assigned to be only of type A, right?

x is of type A, which is subset of type A | B. So it depends on what type requires your function:

const requireAOrB = (value: A | B) => {
 // x is allowed
};

const requireA = (value: A) => {
  // x is allowed
};

const requireB = (value: B) => {
  // x is not allowed
};

x is not of type A and B at the same time, it just fulfills A | B superset.

CodePudding user response:

The short answer is you can't. TypeScript is compiled to JavaScript and types (at least types like that) do not exist in JavaScript. That means all the types you define are gone at runtime and you have no way of doing a runtime check to determine of which type a variable is.

There are exceptions to this. For example you can determine at runtime if a variable is a string or number using the typeof keyword:

const x: string | number = 'foo';
if (typeof x === 'string') {
  // do something
}

Another exception are classes. You can check if a variable is an instance of a specific class using the instanceof keyword:

class A { }
class B { }

const x: A | B = new A();

if (x instanceof A) {
  // do something
}

These things will work as expected and typescript also understands these keywords and will narrow types correctly.

For a situation like yours where the types you are using are typescript types that will be omitted at runtime, you really have to compare the values because the types are simply not available at runtime.

  •  Tags:  
  • Related