Base signatures resolve only the type parameters local to the signature, not all type parameters (#42703)

This commit is contained in:
Wesley Wigham 2021-02-23 16:17:57 -08:00 committed by GitHub
parent 6da262591c
commit 8d58c8d90b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 2 deletions

View File

@ -12244,9 +12244,20 @@ namespace ts {
function getBaseSignature(signature: Signature) {
const typeParameters = signature.typeParameters;
if (typeParameters) {
if (signature.baseSignatureCache) {
return signature.baseSignatureCache;
}
const typeEraser = createTypeEraser(typeParameters);
const baseConstraints = map(typeParameters, tp => instantiateType(getBaseConstraintOfType(tp), typeEraser) || unknownType);
return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true);
const baseConstraintMapper = createTypeMapper(typeParameters, map(typeParameters, tp => getConstraintOfTypeParameter(tp) || unknownType));
let baseConstraints: readonly Type[] = map(typeParameters, tp => instantiateType(tp, baseConstraintMapper) || unknownType);
// Run N type params thru the immediate constraint mapper up to N times
// This way any noncircular interdependent type parameters are definitely resolved to their external dependencies
for (let i = 0; i < typeParameters.length - 1; i++) {
baseConstraints = instantiateTypes(baseConstraints, baseConstraintMapper);
}
// and then apply a type eraser to remove any remaining circularly dependent type parameters
baseConstraints = instantiateTypes(baseConstraints, typeEraser);
return signature.baseSignatureCache = instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true);
}
return signature;
}

View File

@ -5550,6 +5550,8 @@ namespace ts {
/* @internal */
canonicalSignatureCache?: Signature; // Canonical version of signature (deferred)
/* @internal */
baseSignatureCache?: Signature; // Base version of signature (deferred)
/* @internal */
optionalCallSignatureCache?: { inner?: Signature, outer?: Signature }; // Optional chained call version of signature (deferred)
/* @internal */
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison

View File

@ -0,0 +1,7 @@
//// [conditionalTypeGenericInSignatureTypeParameterConstraint.ts]
// should be x
type H_inline1<x> = (<o extends x>() => o) extends (() => infer o) ? o : never;
type Result = H_inline1<string>; // should be `string`
//// [conditionalTypeGenericInSignatureTypeParameterConstraint.js]

View File

@ -0,0 +1,15 @@
=== tests/cases/compiler/conditionalTypeGenericInSignatureTypeParameterConstraint.ts ===
// should be x
type H_inline1<x> = (<o extends x>() => o) extends (() => infer o) ? o : never;
>H_inline1 : Symbol(H_inline1, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 0, 0))
>x : Symbol(x, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 1, 15))
>o : Symbol(o, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 1, 22))
>x : Symbol(x, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 1, 15))
>o : Symbol(o, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 1, 22))
>o : Symbol(o, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 1, 63))
>o : Symbol(o, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 1, 63))
type Result = H_inline1<string>; // should be `string`
>Result : Symbol(Result, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 1, 79))
>H_inline1 : Symbol(H_inline1, Decl(conditionalTypeGenericInSignatureTypeParameterConstraint.ts, 0, 0))

View File

@ -0,0 +1,8 @@
=== tests/cases/compiler/conditionalTypeGenericInSignatureTypeParameterConstraint.ts ===
// should be x
type H_inline1<x> = (<o extends x>() => o) extends (() => infer o) ? o : never;
>H_inline1 : x
type Result = H_inline1<string>; // should be `string`
>Result : string

View File

@ -0,0 +1,4 @@
// should be x
type H_inline1<x> = (<o extends x>() => o) extends (() => infer o) ? o : never;
type Result = H_inline1<string>; // should be `string`