Don't attach declarations to symbols in mapped types with 'as XXX' clauses (#44609)

* Don't attach declarations to symbols in mapped types with 'as XXX' clauses

* Add test (and tweak comment)

Co-authored-by: Eli Barzilay <eli@barzilay.org>
This commit is contained in:
Anders Hejlsberg
2021-06-16 16:07:33 -07:00
committed by GitHub
parent 4af8333a4e
commit 97b4063d73
6 changed files with 80 additions and 1 deletions

View File

@@ -11148,7 +11148,9 @@ namespace ts {
prop.keyType = keyType;
if (modifiersProp) {
prop.syntheticOrigin = modifiersProp;
prop.declarations = modifiersProp.declarations;
// If the mapped type has an `as XXX` clause, the property name likely won't match the declaration name and
// multiple properties may map to the same name. Thus, we attach no declarations to the symbol.
prop.declarations = nameType ? undefined : modifiersProp.declarations;
}
members.set(propName, prop);
}

View File

@@ -0,0 +1,16 @@
tests/cases/compiler/mappedTypeAsStringTemplate.ts(7,5): error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type '{ xy: number; }'.
Property 'xy' is missing in type '{ x: number; }' but required in type '{ xy: number; }'.
==== tests/cases/compiler/mappedTypeAsStringTemplate.ts (1 errors) ====
// Repro from #44220
function foo<T extends { [K in keyof T as `${Extract<K, string>}y`]: number }>(foox: T) { }
const c = { x: 1 };
foo(c);
~
!!! error TS2345: Argument of type '{ x: number; }' is not assignable to parameter of type '{ xy: number; }'.
!!! error TS2345: Property 'xy' is missing in type '{ x: number; }' but required in type '{ xy: number; }'.

View File

@@ -0,0 +1,15 @@
//// [mappedTypeAsStringTemplate.ts]
// Repro from #44220
function foo<T extends { [K in keyof T as `${Extract<K, string>}y`]: number }>(foox: T) { }
const c = { x: 1 };
foo(c);
//// [mappedTypeAsStringTemplate.js]
// Repro from #44220
function foo(foox) { }
var c = { x: 1 };
foo(c);

View File

@@ -0,0 +1,21 @@
=== tests/cases/compiler/mappedTypeAsStringTemplate.ts ===
// Repro from #44220
function foo<T extends { [K in keyof T as `${Extract<K, string>}y`]: number }>(foox: T) { }
>foo : Symbol(foo, Decl(mappedTypeAsStringTemplate.ts, 0, 0))
>T : Symbol(T, Decl(mappedTypeAsStringTemplate.ts, 2, 13))
>K : Symbol(K, Decl(mappedTypeAsStringTemplate.ts, 2, 26))
>T : Symbol(T, Decl(mappedTypeAsStringTemplate.ts, 2, 13))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>K : Symbol(K, Decl(mappedTypeAsStringTemplate.ts, 2, 26))
>foox : Symbol(foox, Decl(mappedTypeAsStringTemplate.ts, 2, 79))
>T : Symbol(T, Decl(mappedTypeAsStringTemplate.ts, 2, 13))
const c = { x: 1 };
>c : Symbol(c, Decl(mappedTypeAsStringTemplate.ts, 4, 5))
>x : Symbol(x, Decl(mappedTypeAsStringTemplate.ts, 4, 11))
foo(c);
>foo : Symbol(foo, Decl(mappedTypeAsStringTemplate.ts, 0, 0))
>c : Symbol(c, Decl(mappedTypeAsStringTemplate.ts, 4, 5))

View File

@@ -0,0 +1,18 @@
=== tests/cases/compiler/mappedTypeAsStringTemplate.ts ===
// Repro from #44220
function foo<T extends { [K in keyof T as `${Extract<K, string>}y`]: number }>(foox: T) { }
>foo : <T extends { [K in keyof T as `${Extract<K, string>}y`]: number; }>(foox: T) => void
>foox : T
const c = { x: 1 };
>c : { x: number; }
>{ x: 1 } : { x: number; }
>x : number
>1 : 1
foo(c);
>foo(c) : void
>foo : <T extends { [K in keyof T as `${Extract<K, string>}y`]: number; }>(foox: T) => void
>c : { x: number; }

View File

@@ -0,0 +1,7 @@
// Repro from #44220
function foo<T extends { [K in keyof T as `${Extract<K, string>}y`]: number }>(foox: T) { }
const c = { x: 1 };
foo(c);