Skip to content

Generic with type inference in conditional type not evaluated into definitive typeΒ #42636

Closed
@turtleflyer

Description

@turtleflyer

Bug Report

πŸ”Ž Search Terms

generic conditional type inference not evaluated

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about generic and conditional types

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type SubGuard<A, X extends [A]> = X;

type IsSub<M extends any[], S extends any[]> = M extends [
  ...SubGuard<M[number], infer B>,
  ...S,
  ...any[]
]
  ? B
  : never;

type E0 = IsSub<[1, 2, 3, 4], [2, 3, 4]>; //  Evaluated: type E0 = [1, 2, 3, 4] extends [...infer B, 2, 3, 4, ...any[]] ? B : never

type E1 = [1, 2, 3, 4] extends [...infer B, 2, 3, 4, ...any[]] ? B : never; // type E1 = unknown[]

declare let v0: E0;
declare let v1: E1;
declare let v2: unknown[];

  v0 = v1 = v2 = v1;
// ^ Type 'unknown[]' is not assignable to type 'IsSub<[1, 2, 3, 4], [2, 3, 4]>'.(2322)

v1 = v2 = v0; // Ok

πŸ™ Actual behavior

The generic type being provided with correct parameters IsSub<[1, 2, 3, 4], [2, 3, 4]> appears to get evaluated into a conditianal type literal [1, 2, 3, 4] extends [...infer B, 2, 3, 4, ...any[]] ? B : never

πŸ™‚ Expected behavior

If such a generic has an error in syntax or faces some limitation in the use, the compiler should raise an exception. If it is correct (it looks correct) it must be evaluated into a definitive type, e.g. unknown[]. In contrast, if we change generic:

type IsSub<M extends any[], S extends any[]> = M extends [
  ...SubGuard<M[number], infer B>,
  ...S
]
  ? B
  : never;

it gives us:

type E0 = IsSub<[1, 2, 3, 4], [2, 3, 4]>; //  Evaluated: type E0 = [1]

that is expected.


One more inconsistency in the example:

If we add:

declare let v3: never;

v3 = v0;

the compiler shows an error:

Type 'IsSub<[1, 2, 3, 4], [2, 3, 4]>' is not assignable to type 'never'.
  Type '[M[number]]' is not assignable to type 'never'.(2322)

where we can see type [M[number]] which is absurd since M is not in the context and is the name of a variable in the original generic type IsSub<M extends any[], S extends any[]>.

If we substitute M with [1, 2, 3, 4] it still does not answer what actual type we have:

declare let v4: [[1, 2, 3, 4][number]];

v0 = v4; // Error
v4 = v0; // Ok

Playground

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions