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

Inference regression (5.0.4 vs 4.9.5) with nullable enum function parameter #54005

Closed
cakoose opened this issue Apr 25, 2023 · 3 comments Β· Fixed by #54072
Closed

Inference regression (5.0.4 vs 4.9.5) with nullable enum function parameter #54005

cakoose opened this issue Apr 25, 2023 · 3 comments Β· Fixed by #54072
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue

Comments

@cakoose
Copy link

cakoose commented Apr 25, 2023

Bug Report

πŸ”Ž Search Terms

inference string null function parameter

πŸ•— Version & Regression Information

  • This changed between versions 4.9.5 and 5.0.4

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

enum Thing { a = 'a', b = 'b', };

function f(
    registrationStatusOptions: SelectOptions<Thing>,
    onChange: (status: Thing | null) => void, // <-- Remove the `| null` and the error goes away.
): void {
    select({ // <-- Add an explicit type argument `Thing` and the error goes away.
        options: registrationStatusOptions,
        onChange: onChange, // ERROR in v5.0.4 but not in v4.9.5: Type '(status: Thing | null) => void' is not assignable to type '(key: string) => void'.
    });
}

export function select<KeyT extends string>(props: SelectProps<KeyT>): void {
    throw new Error('hello');
}

export type SelectProps<KeyT extends string> = {
    onChange: (key: KeyT) => void;
    options?: SelectOptions<KeyT>; // <-- Remove the `?` and the error goes away.
};

export type SelectOptions<KeyT extends string> =
    // Comment either of the below union members out and the error goes away.
    | Array<{key: KeyT}>
    | Array<KeyT>;

πŸ™ Actual behavior

  1. Got a type error; see "ERROR" comment above. Looks like the type argument to select(...) is being inferred incorrectly.
  2. Minor perturbations of the code cause the error to go away; see other comments above.

This was extracted from some React UI code.

πŸ™‚ Expected behavior

TypeScript 4.9.5 infers the type argument I wanted. I was hoping TypeScript 5.0.4 would do the same.

@fatcerberus
Copy link

Educated guess: Since this involves enums and the behavior changes between 4.9 and 5.0, this is likely fallout from #50528.

@RyanCavanaugh
Copy link
Member

Not enums.

This is weird since removing the constraint also fixes it. Bisecting.

type Thing = 'a' | 'b';

function f(
    options: SelectOptions<Thing>,
    onChange: (status: Thing | null) => void, // <-- Remove the `| null` and the error goes away.
): void {
    select({ // <-- Add an explicit type argument `Thing` and the error goes away.
        options,
        onChange, // ERROR in v5.0.4 but not in v4.9.5: Type '(status: Thing | null) => void' is not assignable to type '(key: string) => void'.
    });
}

declare function select<KeyT extends string>(props: SelectProps<KeyT>): void;

type SelectProps<KeyT extends string> = {
    options?: SelectOptions<KeyT>; // <-- Remove the `?` and the error goes away.
    onChange: (key: KeyT) => void;
};

type SelectOptions<KeyT extends string> =
    // Comment either of the below union members out and the error goes away.
    | Array<{key: KeyT}>
    | Array<KeyT>;

@typescript-bot
Copy link
Collaborator

The change between origin/release-4.9 and origin/release-5.0 occurred at 28e4c81.

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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants