Skip to content

Never type is not inferred when used from helper function #33193

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

Closed
Hurtak opened this issue Sep 2, 2019 · 6 comments
Closed

Never type is not inferred when used from helper function #33193

Hurtak opened this issue Sep 2, 2019 · 6 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@Hurtak
Copy link

Hurtak commented Sep 2, 2019

TypeScript Version: 3.5.1

Code

type UnionType = "A" | "B"

function getSomething(foo: UnionType): number {
    switch (foo) {
        case "A":
            return 1;
        case "B":
            return 2
        default:
            const _: never = foo;
            return _;
    }
}

function getSomethingInlineNeverFail(foo: UnionType): number {
    switch (foo) {
        case "A":
            return 1;
        default:
            const _: never = foo; // Type '"B"' is not assignable to type 'never'.
            return _;
    }
}

function getSomethingHelperNeverNoFail(foo: UnionType): number {
    switch (foo) {
        case "A":
            return 1;
        default:
            return never(); // No type error
    }
}

function never(): never {
    throw new Error("Should never happen");
}

Expected behavior:
There is type error in getSomethingHelperNeverNoFail function

Actual behavior:
No type error in getSomethingHelperNeverNoFail function

Playground Link: http://www.typescriptlang.org/play/#code/FAFwngDgpgBAqgOwJYHsEBVKwLwwEQCCeMAPvgEJ7DABmArggMYioIwDmUIAyigLZcAFkgTsAFDRQoAXPGRpM0AJSyEdPgCMoAJxgBvYDCMwAzgHckIRoJgSpS-YePPGAQxOxCeaU+d+Y2lx02mwAjADcvn5uHhTeUf5GgSDBbABMCcYAJlA0rnQANiA+idFoJiAwAPqqUABuOjC4kiiRpc7JqdVtxgC+wP20DMysHFy8AiDCogCSCAUiUABy9ToAYq5IBXYycqyKUCowapqNBs7mlta2LQ7niTGeRCXtSUEhMBGZRjl5hcXfMoICrVWoNXTNKThGAAehhMAOMAA5HhKEiYEgTMcUJV3CYkOwEK4NAVYCAUDBwNBkQhVtokQA6QEdd5sKo9Iz9Qb0JgsNBjHj8IQidgACSgBWg2hW4KWKA2Wx2skQ+ywRxOWl09yMlysNh2d0Bj3wz2Zxk6Hy+pV++SKL1eFrYtPBYiU0LhMDllKwMB02hQ2iiXOoPJG-OdOldYLOUSm-rMxygCYAotp-doxHhuIIUIUsonwTBBK4INAEHg3QMgA

@IllusionMH
Copy link
Contributor

IllusionMH commented Sep 2, 2019

Function should accept param of type never, otherwise there should be no checks and TS works correctly.

function getSomethingHelperNeverNoFail(foo: UnionType): number {
    switch (foo) {
        case "A":
            return 1;
        default:
            return never(foo); // you should pass param to function to enable type check
    }
}

function never(val: never): never {
    throw new Error("Should never happen");
}

http://www.typescriptlang.org/play/#code/FAFwngDgpgBAqgOwJYHsEBVKwLwwEQCCeMAPvgEJ7DABmArggMYioIwDmUIAyigLZcAFkgTsAFDRQoAXPGRpM0AJSyEdPgCMoAJxgBvYDCMwAzgHckIRoJgSpS-YePPGAQxOxCeaU+d+Y2lx02mwAjADcvn5uHhTeUf5GgSDBbABMCcYAJlA0rnQANiA+idFoJiAwAPqqUABuOjC4kiiRpc7JqdVtxgC+wP20DMysHFy8AiDCogCSCAUiUABy9ToAYq5IBXYycqyKUCowapqNBs7mlta2LQ7niTGeRCXtSUEhMBGZRjl5hcXfMoICrVWoNXTNKThGAAehhMAOMAA5HhKEiYEgTMcUJV3CYkOwEK4NAVYCAUDBwNBkQhVtokQA6QEdd5sKo9Iz9Qb0JgsNBjHj8IQidgACSgBWg2hW4KWKA2Wx2skQ+ywRxOWl09yMlysNh2d0Bj3wz2Zxk6Hy+pV++SKL1eFrYtPBBuhcJgcspWBgOm0KG0US51B5I35zp0YjqrgKYJ06rpjmcUz9ZmOUFTAFFtH7tGI8NxBChClk0+CYIJXBBoAg8EpIr0gA

UPD. You can even provide helpful exception:

function never(val: never): never {
    throw new Error("Nothing expected, but got: " + val); // or JSON.stringify(val)
}

@Hurtak
Copy link
Author

Hurtak commented Sep 2, 2019

"Function should accept param of type never, otherwise there should be no checks", but why? Shouldn't the never type be inferred from the return value of the function?

@fatcerberus
Copy link

never is the bottom type and therefore assignable to all other types. There is no type error in your code.

@IllusionMH
Copy link
Contributor

There are no problem with returning never as described above.

As for handling functions with never -
probably you are looking for #12825

And you can see related discussion in comment: #14490 (comment)

@Hurtak
Copy link
Author

Hurtak commented Sep 2, 2019

Thanks for the links and explanation. Should I close this issue, since there is overlap with linked issues, or is there some value to keeping it open?

@IllusionMH
Copy link
Contributor

Not sure if there are any actionable items left, so most likely this issue should be closed.

However if you are sure that there are some you can let if open for TS team to decide.

@sandersn sandersn added the Question An issue which isn't directly actionable in code label Sep 3, 2019
@sandersn sandersn closed this as completed Sep 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants