Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Union types in TypeScript - can I achieve this?

I want to achieve the following:

class MyClass {    
  boolProp: boolean;  
}

let a: string | MyClass;
a.boolProp = false; // error

The last line throws an error since that's how typescript works.

Can I achieve the above without an error, but without typeguards? I just want to be able to tell the compiler that a certain variable is either of type a or b, so it should consider it a 'real' union of both type properties and methods, not just the common ones.

I'm familiar with such behaviors from other languages and to my taste this seems like a feature request for typescript.

Am I missing something?

like image 458
Boaz Rymland Avatar asked Jan 23 '17 07:01

Boaz Rymland


2 Answers

You want the complement to type unions, type intersection.

class MyClass {    
  boolProp: boolean;  
}

let a: string & MyClass;
a.boolProp = false; // no error

Type unions announce a variable is one type or another, so the only properties you can reliably access are those common to both. Type intersection announce a variable satisfies both type contracts, so you can access properties that belong to either of its component types -- which is what you want.

like image 70
Paarth Avatar answered Sep 29 '22 06:09

Paarth


Union types, by definition, contain only the common properties:

If we have a value that has a union type, we can only access members that are common to all types in the union

At runtime you'll need to check whether a specific value is a string or MyClass to understand if boolProp is a property of said value, and that's where the type guards come into action.

If in your code you're creating a boolProp property to string instances, then you better do something like:

type MyString = string & { boolProp: boolean };

Then you can use it like so:

let a: MyString | MyClass;
a.boolProp = false; // works

This way you'll differentiate between string instances which have boolProp and instances that don't.

like image 38
Nitzan Tomer Avatar answered Sep 29 '22 07:09

Nitzan Tomer