Skip to content

Union types of sort interface | interface[] and using instanceof Array #2295

Closed
@IanYates

Description

@IanYates

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptDuplicateAn existing issue was already created

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions