33

I was just wondering if it is possible to type array with a union type, so that one array can contain both Apples and Oranges but nothing else.

Something like

var arr : (Apple|Orange)[] = [];

arr.push(apple); //ok
arr.push(orange); //ok
arr.push(1); //error
arr.push("abc"); // error

Needless to say, the example above does not work so this may not be possible, or am I missing something?

2 Answers 2

47
class Apple {
  appleFoo: any;
}

class Orange {
  orangeFoo: any;
}

var arr : Array<Apple|Orange> = [];

var apple = new Apple();
var orange = new Orange();

arr.push(apple); //ok
arr.push(orange); //ok
arr.push(1); //error
arr.push("abc"); // error

var something = arr[0];

if(something instanceof Apple) {
  something.appleFoo; //ok
  something.orangeFoo; //error
} else if(something instanceof Orange) {
  something.appleFoo; //error
  something.orangeFoo; //ok
}
Sign up to request clarification or add additional context in comments.

6 Comments

the definition does not throw an error but you can not access neither properties of Apple nor Orange
I've updated the answer to include a type guard example.
@daniel.sedlacek if they were interfaces rather than classes, it is still possible you'd have to do a bit more work (bit.ly/1Gi14Uu) - i.e. if (arr[0].hasOwnProperty("name")) { var a = <Apple>arr[0]; console.log(a.name); }
Awesome. I wish all this info was somewhere nicely in one place, but I understand TS is moving forward so fast ...
different techniques to make type guards: typescriptlang.org/docs/handbook/…
|
15

As per TS 2.3.4 is as simple as

let someArray: (typeA|typeB)[] = [
  new typeA(),
  new typeB()
]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.