Fixed regression in generic signature instantiation with default type args (#59510)

This commit is contained in:
Mateusz Burzyński 2024-08-09 05:24:10 +02:00 коммит произвёл GitHub
Родитель 278cb9489d
Коммит 1bb1d2a610
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
4 изменённых файлов: 218 добавлений и 2 удалений

Просмотреть файл

@ -16040,8 +16040,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return instantiateSignature(signature, createSignatureTypeMapper(signature, typeArguments), /*eraseTypeParameters*/ true);
}
function getTypeParametersForMapper(signature: Signature) {
return sameMap(signature.typeParameters, tp => tp.mapper ? instantiateType(tp, tp.mapper) : tp);
}
function createSignatureTypeMapper(signature: Signature, typeArguments: readonly Type[] | undefined): TypeMapper {
return createTypeMapper(sameMap(signature.typeParameters!, tp => tp.mapper ? instantiateType(tp, tp.mapper) : tp), typeArguments);
return createTypeMapper(getTypeParametersForMapper(signature)!, typeArguments);
}
function getErasedSignature(signature: Signature): Signature {
@ -34930,7 +34934,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, inferenceContext?: InferenceContext, compareTypes?: TypeComparer): Signature {
const context = createInferenceContext(signature.typeParameters!, signature, InferenceFlags.None, compareTypes);
const context = createInferenceContext(getTypeParametersForMapper(signature)!, signature, InferenceFlags.None, compareTypes);
// We clone the inferenceContext to avoid fixing. For example, when the source signature is <T>(x: T) => T[] and
// the contextual signature is (...args: A) => B, we want to infer the element type of A's constraint (say 'any')
// for T but leave it possible to later infer '[any]' back to A.

Просмотреть файл

@ -0,0 +1,85 @@
//// [tests/cases/compiler/genericCallInferenceConditionalType2.ts] ////
=== genericCallInferenceConditionalType2.ts ===
// https://github.com/microsoft/TypeScript/issues/59490
type ComponentProps<T> = T extends (props: infer P) => unknown ? P : never;
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceConditionalType2.ts, 0, 0))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 2, 20))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 2, 20))
>props : Symbol(props, Decl(genericCallInferenceConditionalType2.ts, 2, 36))
>P : Symbol(P, Decl(genericCallInferenceConditionalType2.ts, 2, 48))
>P : Symbol(P, Decl(genericCallInferenceConditionalType2.ts, 2, 48))
declare function wrapComponent<P>(
>wrapComponent : Symbol(wrapComponent, Decl(genericCallInferenceConditionalType2.ts, 2, 75))
>P : Symbol(P, Decl(genericCallInferenceConditionalType2.ts, 4, 31))
component: (props: P) => unknown,
>component : Symbol(component, Decl(genericCallInferenceConditionalType2.ts, 4, 34))
>props : Symbol(props, Decl(genericCallInferenceConditionalType2.ts, 5, 14))
>P : Symbol(P, Decl(genericCallInferenceConditionalType2.ts, 4, 31))
): (props: P) => unknown;
>props : Symbol(props, Decl(genericCallInferenceConditionalType2.ts, 6, 4))
>P : Symbol(P, Decl(genericCallInferenceConditionalType2.ts, 4, 31))
const WrappedComponent = wrapComponent(
>WrappedComponent : Symbol(WrappedComponent, Decl(genericCallInferenceConditionalType2.ts, 8, 5))
>wrapComponent : Symbol(wrapComponent, Decl(genericCallInferenceConditionalType2.ts, 2, 75))
<T extends string = "span">(props: {
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 9, 3))
>props : Symbol(props, Decl(genericCallInferenceConditionalType2.ts, 9, 30))
as?: T | undefined;
>as : Symbol(as, Decl(genericCallInferenceConditionalType2.ts, 9, 38))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 9, 3))
className?: string;
>className : Symbol(className, Decl(genericCallInferenceConditionalType2.ts, 10, 23))
}) => {
return null;
},
);
type RetrievedProps = ComponentProps<typeof WrappedComponent>;
>RetrievedProps : Symbol(RetrievedProps, Decl(genericCallInferenceConditionalType2.ts, 15, 2))
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceConditionalType2.ts, 0, 0))
>WrappedComponent : Symbol(WrappedComponent, Decl(genericCallInferenceConditionalType2.ts, 8, 5))
declare const f: <T>(f: (x: T) => unknown) => (x: T) => unknown
>f : Symbol(f, Decl(genericCallInferenceConditionalType2.ts, 19, 13))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 19, 18))
>f : Symbol(f, Decl(genericCallInferenceConditionalType2.ts, 19, 21))
>x : Symbol(x, Decl(genericCallInferenceConditionalType2.ts, 19, 25))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 19, 18))
>x : Symbol(x, Decl(genericCallInferenceConditionalType2.ts, 19, 47))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 19, 18))
declare const g: <T extends unknown = string>(x: { foo: T }) => unknown
>g : Symbol(g, Decl(genericCallInferenceConditionalType2.ts, 20, 13))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 20, 18))
>x : Symbol(x, Decl(genericCallInferenceConditionalType2.ts, 20, 46))
>foo : Symbol(foo, Decl(genericCallInferenceConditionalType2.ts, 20, 50))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 20, 18))
const h = f(g)
>h : Symbol(h, Decl(genericCallInferenceConditionalType2.ts, 22, 5))
>f : Symbol(f, Decl(genericCallInferenceConditionalType2.ts, 19, 13))
>g : Symbol(g, Decl(genericCallInferenceConditionalType2.ts, 20, 13))
type FirstParameter<T> = T extends (x: infer P) => unknown ? P : unknown
>FirstParameter : Symbol(FirstParameter, Decl(genericCallInferenceConditionalType2.ts, 22, 14))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 24, 20))
>T : Symbol(T, Decl(genericCallInferenceConditionalType2.ts, 24, 20))
>x : Symbol(x, Decl(genericCallInferenceConditionalType2.ts, 24, 36))
>P : Symbol(P, Decl(genericCallInferenceConditionalType2.ts, 24, 44))
>P : Symbol(P, Decl(genericCallInferenceConditionalType2.ts, 24, 44))
type X = FirstParameter<typeof h>['foo']
>X : Symbol(X, Decl(genericCallInferenceConditionalType2.ts, 24, 72))
>FirstParameter : Symbol(FirstParameter, Decl(genericCallInferenceConditionalType2.ts, 22, 14))
>h : Symbol(h, Decl(genericCallInferenceConditionalType2.ts, 22, 5))

Просмотреть файл

@ -0,0 +1,98 @@
//// [tests/cases/compiler/genericCallInferenceConditionalType2.ts] ////
=== genericCallInferenceConditionalType2.ts ===
// https://github.com/microsoft/TypeScript/issues/59490
type ComponentProps<T> = T extends (props: infer P) => unknown ? P : never;
>ComponentProps : ComponentProps<T>
> : ^^^^^^^^^^^^^^^^^
>props : P
> : ^
declare function wrapComponent<P>(
>wrapComponent : <P>(component: (props: P) => unknown) => (props: P) => unknown
> : ^ ^^ ^^ ^^^^^
component: (props: P) => unknown,
>component : (props: P) => unknown
> : ^ ^^ ^^^^^
>props : P
> : ^
): (props: P) => unknown;
>props : P
> : ^
const WrappedComponent = wrapComponent(
>WrappedComponent : <T extends string = "span">(props: { as?: T | undefined; className?: string; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^
>wrapComponent( <T extends string = "span">(props: { as?: T | undefined; className?: string; }) => { return null; },) : <T extends string = "span">(props: { as?: T | undefined; className?: string; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^
>wrapComponent : <P>(component: (props: P) => unknown) => (props: P) => unknown
> : ^ ^^ ^^ ^^^^^
<T extends string = "span">(props: {
><T extends string = "span">(props: { as?: T | undefined; className?: string; }) => { return null; } : <T extends string = "span">(props: { as?: T | undefined; className?: string; }) => null
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^^^^^
>props : { as?: T | undefined; className?: string; }
> : ^^^^^^^ ^^^^^^^^^^^^^^ ^^^
as?: T | undefined;
>as : T | undefined
> : ^^^^^^^^^^^^^
className?: string;
>className : string | undefined
> : ^^^^^^^^^^^^^^^^^^
}) => {
return null;
},
);
type RetrievedProps = ComponentProps<typeof WrappedComponent>;
>RetrievedProps : { as?: string | undefined; className?: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^
>WrappedComponent : <T extends string = "span">(props: { as?: T | undefined; className?: string; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^
declare const f: <T>(f: (x: T) => unknown) => (x: T) => unknown
>f : <T>(f: (x: T) => unknown) => (x: T) => unknown
> : ^ ^^ ^^ ^^^^^
>f : (x: T) => unknown
> : ^ ^^ ^^^^^
>x : T
> : ^
>x : T
> : ^
declare const g: <T extends unknown = string>(x: { foo: T }) => unknown
>g : <T extends unknown = string>(x: { foo: T; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^
>x : { foo: T; }
> : ^^^^^^^ ^^^
>foo : T
> : ^
const h = f(g)
>h : <T extends unknown = string>(x: { foo: T; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^
>f(g) : <T extends unknown = string>(x: { foo: T; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^
>f : <T>(f: (x: T) => unknown) => (x: T) => unknown
> : ^ ^^ ^^ ^^^^^
>g : <T extends unknown = string>(x: { foo: T; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^ ^^^^^
type FirstParameter<T> = T extends (x: infer P) => unknown ? P : unknown
>FirstParameter : FirstParameter<T>
> : ^^^^^^^^^^^^^^^^^
>x : P
> : ^
type X = FirstParameter<typeof h>['foo']
>X : unknown
> : ^^^^^^^
>h : <T extends unknown = string>(x: { foo: T; }) => unknown
> : ^ ^^^^^^^^^ ^^^^^^^^^^^ ^^^^^^^^^ ^^^^^^^^

Просмотреть файл

@ -0,0 +1,29 @@
// @strict: true
// @noEmit: true
// https://github.com/microsoft/TypeScript/issues/59490
type ComponentProps<T> = T extends (props: infer P) => unknown ? P : never;
declare function wrapComponent<P>(
component: (props: P) => unknown,
): (props: P) => unknown;
const WrappedComponent = wrapComponent(
<T extends string = "span">(props: {
as?: T | undefined;
className?: string;
}) => {
return null;
},
);
type RetrievedProps = ComponentProps<typeof WrappedComponent>;
declare const f: <T>(f: (x: T) => unknown) => (x: T) => unknown
declare const g: <T extends unknown = string>(x: { foo: T }) => unknown
const h = f(g)
type FirstParameter<T> = T extends (x: infer P) => unknown ? P : unknown
type X = FirstParameter<typeof h>['foo']