question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Union Type inference not working in class (ts version 1.4)

See original GitHub issue

Hi, Union type inference is not working inside classes functions. For example trying to compile the below code :

type NameOrNameArray = string | string[];

class NameCreator {

    constructor(public name:NameOrNameArray) {}

    createName():string {
        if (typeof this.name === "string") {
            return name;
        }
        else {
            this.name.forEach((elem)=>{
                console.log(elem);
            });
            return this.name.join(" ");
        }
    }
}

gives the error :

Property 'forEach' does not exist on type 'string | string[]'.

The same code works well when using a function. Same error in Visual studio and in the Playground.

Issue Analytics

  • State:open
  • Created 9 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
ahejlsbergcommented, Jan 17, 2015

Type guards only work on simple variables, not properties of an object, so you need to copy the property into a local variable.

type NameOrNameArray = string | string[];

class NameCreator {

    constructor(public name: NameOrNameArray) {}

    createName(): string {
        var name = this.name;  // Copy into variable
        if (typeof name === "string") {
            return name;
        }
        else {
            name.forEach(elem => {
                console.log(elem);
            });
            return name.join(" ");
        }
    }
}

We have this restriction because we want to track (to the best of our abilities) that there are no assignments to the variable in the guarded section. This is pretty much impossible to do correctly for properties without extensive flow and alias analysis. For example:

function printString(s: string) { ... }
class Foo {
    name: string | string[];
    foo() {
        if (typeof this.name === "string") {
            this.bar();
            printString(this.name);  // Ok?
        }
    }
    bar() {
        this.name = ["hello"];
    }
}

This is just a simple example. You can construct increasingly impossible ones with little effort.

A possible alternative to our current design is to allow type guards to work on dotted names of the form x.y.z or this.x.y.z and to ignore the effects of assignments to such names (or parts of them). But it would mean that we wouldn’t catch errors like the one in the example above.

1reaction
erichillahcommented, Jan 17, 2015

I am able to remove the error only by using explicit type assertion

(<string[]>this.name).forEach((elem)=>{
    console.log(elem);
 });
 return (<string[]>this.name).join(" ");
Read more comments on GitHub >

github_iconTop Results From Across the Web

Handbook - Unions and Intersection Types - TypeScript
How to use unions and intersection types in TypeScript. ... The problem with padLeft in the above example is that its padding parameter...
Read more >
Why is type inference not working on union types when one of ...
When I use a union type for which one of the type is any , the TypeScript editor does not seem to resolve...
Read more >
TypeScript 1.6
<reference path="react.d.ts" /> interface Props { name: string; } class ... A union type A | B represents an entity that is either...
Read more >
Learn TypeScript: Union Types Cheatsheet - Codecademy
Since a variable of a union type can assume one of several different types, you can help TypeScript infer the correct variable type...
Read more >
TypeScript - Wikipedia
TypeScript is a free and open source programming language developed and maintained by Microsoft. It is a strict syntactical superset of JavaScript and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found