Skip to content

union types not type guarded #32928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
npenin opened this issue Aug 16, 2019 · 2 comments
Open

union types not type guarded #32928

npenin opened this issue Aug 16, 2019 · 2 comments
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone

Comments

@npenin
Copy link

npenin commented Aug 16, 2019

TypeScript Version: 3.5.2

**Search Terms:extended function type restriction

Code

class C
{
    name: string;
    constructor(private handler: F)
    {
        this.name = handler.name;
    }
}

type F = (...args: any[]) => any;

type F2 = F & { inject?: string[] }

function f(x: C | F2):C
{
    if (typeof x == 'function')
        x = new C(f);

    return x;
}

Expected behavior: x in function f should be of type C at the point of the return statement

Actual behavior: x is considered as C or F2, apparently because of the combined type (it works well if we replace F2 with F)

Playground Link: https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEDCBQBve1XQHZgLYFMBc0EALgE4CW6A5gNwprAD26xJArsEQyQBQAO5ANzBEc0ABZh0AExA4SBAGIBKOqmRoN0ImLIQAdJlzQAvOMky5B7DloaAvvAfwiAT16iFJ6Nz2+wJSggCSRcAbQBdJRMAPmgQ2mc3DwAmL08AMmhEaAoAKxwOAH4CFgpKCOgnADNWdA4yJmgq7gAPAlhoAB9oBWSlPAR1NDIq71d3BlGWk1MAchq6ogb0WZVNNGnTdBwAdzhuKqUEjRIcIlYSdGgW2jsgA

Related Issues: #27143

@npenin npenin changed the title combined types union types not type guarded Aug 16, 2019
@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Aug 16, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.7.0 milestone Aug 16, 2019
@RyanCavanaugh
Copy link
Member

@orta looks like we're not recognizing that typeof F2 should be always "function" even though it's in an intersection with something whose typeof result would be "object"

@npenin thanks for the nice repro!

@orta
Copy link
Contributor

orta commented Oct 15, 2019

Cool makes sense, here's a smaller test case also:

// Callable
type F = (...args: any[]) => any;
// Callable but intersected
type F2 = F & { inject?: string[] }

declare const a: string | F2

if (typeof a == 'function') {
    // only F2
    a
} else {
    // Should be only a string
    a
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue Rescheduled This issue was previously scheduled to an earlier milestone
Projects
None yet
5 participants