Skip to content
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

Typescript 4.2.x - incorrectly infered generic return type of a record union (extra undefined) #43943

Open
TheEdward162 opened this issue May 4, 2021 · 2 comments
Assignees
Labels
Bug A bug in TypeScript Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros
Milestone

Comments

@TheEdward162
Copy link

TheEdward162 commented May 4, 2021

Bug Report

🔎 Search Terms

undefined, generic inference, typescript 4.2

🕗 Version & Regression Information

4.2.0-beta - 4.3.0-dev.20210504 (everything since 4.2 beta, including all stable releases)
NOT in 4.1.x or before

  • This changed between versions 4.1.x and 4.2.x+

The return type inference of the the arrow function hasn't changed, according to the playground it was always infered as { kind: "failure"; value?: undefined; } | { kind: "success"; value: number; }. However, before 4.2. the type of the generic function above it (the andThen) was correctly narrowed down to AndThenResult<number>. This happened even without explicit type annotations, as one would expect.

In 4.2+ the undefined gets propagated into andThen<number | undefined> and this breaks the assignment (and my expectations).

⏯ Playground Link

Playground link with relevant code

💻 Code

// @strict: true
type AndThenResult<T> = { kind: 'success', value: T } | { kind: 'failure' };

function andThen<U>(
    fun: (_: number) => AndThenResult<U>
) {
    return fun(1)
}
//    V error here, type inference gets `AndThenResult<number | undefined>` from `andThen` in TS 4.2+
const a: AndThenResult<number> = andThen(
    // looks like this function infers { kind: "failure"; value?: undefined; } | { kind: "success"; value: number; } on any TS version in the playground
    // however the undefined only gets propagated up in 4.2+
    x => {
        if (x === 1) {
            return { kind: 'failure' }
        }
        return {
            kind: 'success',
            value: x
        }
    }
)

🙁 Actual behavior

The types don't match and the code doesn't compile. The return type of andThen(fn) is different than that expected on a.

🙂 Expected behavior

The types do match, the function return type is narrowed to AndThenResult<number> and nothing breaks.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label May 4, 2021
@RyanCavanaugh RyanCavanaugh added this to the Backlog milestone May 4, 2021
@typescript-bot typescript-bot added the Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros label May 21, 2024
@typescript-bot
Copy link
Collaborator

The change between v4.1.5 and v4.2.3 occurred at 22bee77.

@typescript-bot
Copy link
Collaborator

typescript-bot commented May 22, 2024

👋 Hi, I'm the Repro bot. I can help narrow down and track compiler bugs across releases! This comment reflects the current state of the repro in the issue body running against the nightly TypeScript.


Issue body code block by @TheEdward162

❌ Failed: -

  • Type 'AndThenResult' is not assignable to type 'AndThenResult'. Type '{ kind: "success"; value: number | undefined; }' is not assignable to type 'AndThenResult'. Type '{ kind: "success"; value: number | undefined; }' is not assignable to type '{ kind: "success"; value: number; }'. Types of property 'value' are incompatible. Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.

Historical Information
Version Reproduction Outputs
5.0.2, 5.1.3, 5.2.2, 5.3.2, 5.4.2

❌ Failed: -

  • Type 'AndThenResult' is not assignable to type 'AndThenResult'. Type '{ kind: "success"; value: number | undefined; }' is not assignable to type 'AndThenResult'. Type '{ kind: "success"; value: number | undefined; }' is not assignable to type '{ kind: "success"; value: number; }'. Types of property 'value' are incompatible. Type 'number | undefined' is not assignable to type 'number'. Type 'undefined' is not assignable to type 'number'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Has Repro This issue has compiler-backed repros: https://aka.ms/ts-repros
Projects
None yet
Development

No branches or pull requests

4 participants