Skip to content

4.9 regression on conditional type #51540

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
testerez opened this issue Nov 15, 2022 · 7 comments
Closed

4.9 regression on conditional type #51540

testerez opened this issue Nov 15, 2022 · 7 comments
Assignees
Labels
Fixed A PR has been merged for this issue

Comments

@testerez
Copy link

testerez commented Nov 15, 2022

Bug Report

πŸ”Ž Search Terms

4.9 Type 'number' does not satisfy the constraint

πŸ•— Version & Regression Information

This changed between versions 4.8 and 4.9.3

⏯ Playground Link

tsplay.dev/NdrGyW

πŸ’» Code

type Decrement<N extends number> = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10][N]

type PathImpl<T, K extends keyof T, Depth extends number> = Depth extends 0
  ? ''
  : K extends string | number
  ? T[K] extends Record<string, any>
    ? T[K] extends ArrayLike<any>
      ? K | `${K}.${PathImpl<T[K], number, Decrement<Depth>>}`
      : K | `${K}.${PathImpl<T[K], keyof T[K], Decrement<Depth>>}`
    : K
  : never

export type ObjectPath<T> = PathImpl<T, keyof T, 10> | keyof T

πŸ™ Actual behavior

Type 'number' does not satisfy the constraint 'keyof T[K]'.

πŸ™‚ Expected behavior

Since T[K] extends ArrayLike<any> then I should be able to index by number. This was working on 4.8

@Tobias-Scholz
Copy link
Contributor

Tobias-Scholz commented Nov 15, 2022

Here is a slightly smaller example to reproduce the issue.

Playground

type PathImpl<T, K extends keyof T> = 
  K extends string | number
  ? T[K] extends Record<string, any>
    ? T[K] extends ArrayLike<any>
      ? PathImpl<T[K], number>
      : never
    : never
  : never

All three conditionals are needed to reproduce the error.

There is no error if you remove the first conditional.

type PathImpl<T, K extends keyof T> = 
  T[K] extends Record<string, any>
    ? T[K] extends ArrayLike<any>
      ? PathImpl<T[K], number>
      : never
    : never

Which seems counterintuitive to me.

@cjbarth
Copy link

cjbarth commented Nov 15, 2022

I think we might have a similar issue, but it is related to keyof typeof this.privateMember. See node-saml/node-saml#218

@typescript-bot
Copy link
Collaborator

The change between release-4.8 and main occurred at 6e8337e.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Nov 18, 2022
@JGJP
Copy link

JGJP commented Mar 10, 2023

Seeing a similar issue in @storybook/components popperjs typing, it fails with this message:

Type 'Options' does not satisfy the constraint 'Obj'

where the code looks like this:

export declare type Modifier<Name, Options> = {
    name: Name;
    enabled: boolean;
    phase: ModifierPhases;
    requires?: Array<string>;
    requiresIfExists?: Array<string>;
    fn: (arg0: ModifierArguments<Options>) => State | void; // <-- fails here
    effect?: (arg0: ModifierArguments<Options>) => (() => void) | void; // <-- and here
    options?: Partial<Options>;
    data?: Obj;
};

export declare type ModifierArguments<Options extends Obj> = {
    state: State;
    instance: Instance;
    options: Partial<Options>;
    name: string;
};

export declare type Obj = {
    [key: string]: any;
};

So it looks like it's failing to assign an untyped generic arg to { [key: string]: any }. Is this expected?

@RyanCavanaugh
Copy link
Member

@JGJP that looks like a correct error to me (kinda hard to say since the example is self-contained). Options is unconstrained; if you believe that an unconstrained type parameter should be allowable to pass to a type parameter constrained to Obj, why did you write the extends Obj constraint in the first place?

@JGJP
Copy link

JGJP commented Mar 12, 2023

@RyanCavanaugh this is not my code, it's from popperjs typings, used by @storybook/components. It's only broken after upgrading TS, so I assume it was passing type checks before (4.6)

@ahejlsberg ahejlsberg added Fixed A PR has been merged for this issue and removed Needs Investigation This issue needs a team member to investigate its status. labels Oct 25, 2023
@ahejlsberg
Copy link
Member

This issue no longer reproduces. Looks like it was fixed in TS 5.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Fixed A PR has been merged for this issue
Projects
None yet
Development

No branches or pull requests

7 participants