Fixed regression in generic signature instantiation with default type args (#59510)
This commit is contained in:
Родитель
278cb9489d
Коммит
1bb1d2a610
|
@ -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']
|
Загрузка…
Ссылка в новой задаче