mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 16:38:05 -06:00
When instantiating a mapped type, clone the type parameter. (#27597)
This gives the type parameter returned by getTypeParameterFromMappedType an accurate constraint. Fixes #27596.
This commit is contained in:
parent
4d504f9b30
commit
d19fb98ec6
@ -6850,7 +6850,7 @@ namespace ts {
|
||||
|
||||
function getConstraintTypeFromMappedType(type: MappedType) {
|
||||
return type.constraintType ||
|
||||
(type.constraintType = instantiateType(getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)), type.mapper || identityMapper) || errorType);
|
||||
(type.constraintType = getConstraintOfTypeParameter(getTypeParameterFromMappedType(type)) || errorType);
|
||||
}
|
||||
|
||||
function getTemplateTypeFromMappedType(type: MappedType) {
|
||||
@ -10413,6 +10413,12 @@ namespace ts {
|
||||
const result = <AnonymousType>createObjectType(type.objectFlags | ObjectFlags.Instantiated, type.symbol);
|
||||
if (type.objectFlags & ObjectFlags.Mapped) {
|
||||
(<MappedType>result).declaration = (<MappedType>type).declaration;
|
||||
// C.f. instantiateSignature
|
||||
const origTypeParameter = getTypeParameterFromMappedType(<MappedType>type);
|
||||
const freshTypeParameter = cloneTypeParameter(origTypeParameter);
|
||||
(<MappedType>result).typeParameter = freshTypeParameter;
|
||||
mapper = combineTypeMappers(makeUnaryTypeMapper(origTypeParameter, freshTypeParameter), mapper);
|
||||
freshTypeParameter.mapper = mapper;
|
||||
}
|
||||
result.target = type;
|
||||
result.mapper = mapper;
|
||||
|
||||
14
tests/baselines/reference/mappedTypeParameterConstraint.js
Normal file
14
tests/baselines/reference/mappedTypeParameterConstraint.js
Normal file
@ -0,0 +1,14 @@
|
||||
//// [mappedTypeParameterConstraint.ts]
|
||||
// Repro for #27596
|
||||
|
||||
type MyMap<T> = {[P in keyof T]: T[keyof T]};
|
||||
function foo<U>(arg: U): MyMap<U> {
|
||||
return arg;
|
||||
}
|
||||
|
||||
|
||||
//// [mappedTypeParameterConstraint.js]
|
||||
// Repro for #27596
|
||||
function foo(arg) {
|
||||
return arg;
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
=== tests/cases/compiler/mappedTypeParameterConstraint.ts ===
|
||||
// Repro for #27596
|
||||
|
||||
type MyMap<T> = {[P in keyof T]: T[keyof T]};
|
||||
>MyMap : Symbol(MyMap, Decl(mappedTypeParameterConstraint.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(mappedTypeParameterConstraint.ts, 2, 11))
|
||||
>P : Symbol(P, Decl(mappedTypeParameterConstraint.ts, 2, 18))
|
||||
>T : Symbol(T, Decl(mappedTypeParameterConstraint.ts, 2, 11))
|
||||
>T : Symbol(T, Decl(mappedTypeParameterConstraint.ts, 2, 11))
|
||||
>T : Symbol(T, Decl(mappedTypeParameterConstraint.ts, 2, 11))
|
||||
|
||||
function foo<U>(arg: U): MyMap<U> {
|
||||
>foo : Symbol(foo, Decl(mappedTypeParameterConstraint.ts, 2, 45))
|
||||
>U : Symbol(U, Decl(mappedTypeParameterConstraint.ts, 3, 13))
|
||||
>arg : Symbol(arg, Decl(mappedTypeParameterConstraint.ts, 3, 16))
|
||||
>U : Symbol(U, Decl(mappedTypeParameterConstraint.ts, 3, 13))
|
||||
>MyMap : Symbol(MyMap, Decl(mappedTypeParameterConstraint.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(mappedTypeParameterConstraint.ts, 3, 13))
|
||||
|
||||
return arg;
|
||||
>arg : Symbol(arg, Decl(mappedTypeParameterConstraint.ts, 3, 16))
|
||||
}
|
||||
|
||||
@ -0,0 +1,14 @@
|
||||
=== tests/cases/compiler/mappedTypeParameterConstraint.ts ===
|
||||
// Repro for #27596
|
||||
|
||||
type MyMap<T> = {[P in keyof T]: T[keyof T]};
|
||||
>MyMap : MyMap<T>
|
||||
|
||||
function foo<U>(arg: U): MyMap<U> {
|
||||
>foo : <U>(arg: U) => MyMap<U>
|
||||
>arg : U
|
||||
|
||||
return arg;
|
||||
>arg : U
|
||||
}
|
||||
|
||||
6
tests/cases/compiler/mappedTypeParameterConstraint.ts
Normal file
6
tests/cases/compiler/mappedTypeParameterConstraint.ts
Normal file
@ -0,0 +1,6 @@
|
||||
// Repro for #27596
|
||||
|
||||
type MyMap<T> = {[P in keyof T]: T[keyof T]};
|
||||
function foo<U>(arg: U): MyMap<U> {
|
||||
return arg;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user