Description
In TypeScript playground, the "New Features" option gives this code
type NameOrNameArray = string | string[];
function createName(name: NameOrNameArray) {
if (typeof name === "string") {
return name;
}
else {
return name.join(" ");
}
}
var greetingMessage = `Greetings, ${createName(["Sam", "Smith"]) }`;
alert(greetingMessage);
If I make a type such as
interface Guid {
toLowerCase:()=>string;
}
(since I'm using TypeLite to get some C# types in my TypeScript I have a Guid type but basically treat Guids as strings so toLowerCase() is enough to discriminate for my purposes).
Anyway, if I then modify the playground code to be
interface Guid {
toLowerCase:()=>string;
}
type GuidOrGuidArray = Guid | Guid[];
function createGuid(g: GuidOrGuidArray) {
if (g instanceof Array) {
//intellisense on g. should give me array things
var x = g[0]; //This SHOULD compile
}
else {
//intellisense on g. should give me toLowerCase() as my only option
var y = g.toLowerCase(); ///This SHOULD compile
}
}
Instead I get the type of x
to be any and y
fails to compile. In both cases, the popup hint in the playground (and in Visual Studio) gives the indication that the type of g within each branch of the if is still the union type.
You'll note that I switched the if block around so that I'm using instanceof Array rather than typeof === "string". That's because I've tried it the other way and wasn't surprised that it didn't work since my Guid interface doesn't extend string in any way and typeof [] gives object.
Should this work? At the moment I'm doing the kludge workarounds...
var x = <Guid[]>g[0];
and
var y = (<Guid>g).toLowerCase();
It'd be 💯 if instanceof Array worked to discriminate between the array and non-array in the union type.