diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e0672300f1cd4..7c1acce01f4b4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9656,6 +9656,7 @@ namespace ts { if (isTypeUsableAsPropertyName(t)) { const propName = getPropertyNameFromType(t); const modifiersProp = getPropertyOfType(modifiersType, propName); + const templateProp = (templateType.flags & TypeFlags.IndexedAccess) && getPropertyOfType((templateType).objectType, propName); const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional || !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional); const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly || @@ -9663,12 +9664,12 @@ namespace ts { const stripOptional = strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional; const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, CheckFlags.Mapped | (isReadonly ? CheckFlags.Readonly : 0) | (stripOptional ? CheckFlags.StripOptional : 0)); + prop.mappedType = type; prop.mapper = templateMapper; - if (modifiersProp) { - prop.syntheticOrigin = modifiersProp; - prop.declarations = modifiersProp.declarations; - } + + prop.syntheticOrigin = templateProp || modifiersProp; + prop.declarations = templateProp && templateProp.declarations || modifiersProp && modifiersProp.declarations || undefined!; prop.nameType = t; members.set(propName, prop); } diff --git a/tests/baselines/reference/mappedTypes7.js b/tests/baselines/reference/mappedTypes7.js new file mode 100644 index 0000000000000..61fd828ef6db0 --- /dev/null +++ b/tests/baselines/reference/mappedTypes7.js @@ -0,0 +1,23 @@ +//// [mappedTypes7.ts] +interface I { + a: number; + b: number; +} +type J = { + [K in 'b' | 'a']: I[K] +}; + +type L = Pick + +declare const j: J; +j.a; +j.b; + +declare const l: L +l.a + + +//// [mappedTypes7.js] +j.a; +j.b; +l.a; diff --git a/tests/baselines/reference/mappedTypes7.symbols b/tests/baselines/reference/mappedTypes7.symbols new file mode 100644 index 0000000000000..2dd2f63b98798 --- /dev/null +++ b/tests/baselines/reference/mappedTypes7.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/types/mapped/mappedTypes7.ts === +interface I { +>I : Symbol(I, Decl(mappedTypes7.ts, 0, 0)) + + a: number; +>a : Symbol(I.a, Decl(mappedTypes7.ts, 0, 13)) + + b: number; +>b : Symbol(I.b, Decl(mappedTypes7.ts, 1, 14)) +} +type J = { +>J : Symbol(J, Decl(mappedTypes7.ts, 3, 1)) + + [K in 'b' | 'a']: I[K] +>K : Symbol(K, Decl(mappedTypes7.ts, 5, 5)) +>I : Symbol(I, Decl(mappedTypes7.ts, 0, 0)) +>K : Symbol(K, Decl(mappedTypes7.ts, 5, 5)) + +}; + +type L = Pick +>L : Symbol(L, Decl(mappedTypes7.ts, 6, 2)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) +>J : Symbol(J, Decl(mappedTypes7.ts, 3, 1)) + +declare const j: J; +>j : Symbol(j, Decl(mappedTypes7.ts, 10, 13)) +>J : Symbol(J, Decl(mappedTypes7.ts, 3, 1)) + +j.a; +>j.a : Symbol(a, Decl(mappedTypes7.ts, 0, 13)) +>j : Symbol(j, Decl(mappedTypes7.ts, 10, 13)) +>a : Symbol(a, Decl(mappedTypes7.ts, 0, 13)) + +j.b; +>j.b : Symbol(b, Decl(mappedTypes7.ts, 1, 14)) +>j : Symbol(j, Decl(mappedTypes7.ts, 10, 13)) +>b : Symbol(b, Decl(mappedTypes7.ts, 1, 14)) + +declare const l: L +>l : Symbol(l, Decl(mappedTypes7.ts, 14, 13)) +>L : Symbol(L, Decl(mappedTypes7.ts, 6, 2)) + +l.a +>l.a : Symbol(a, Decl(mappedTypes7.ts, 0, 13)) +>l : Symbol(l, Decl(mappedTypes7.ts, 14, 13)) +>a : Symbol(a, Decl(mappedTypes7.ts, 0, 13)) + diff --git a/tests/baselines/reference/mappedTypes7.types b/tests/baselines/reference/mappedTypes7.types new file mode 100644 index 0000000000000..36939a5bbc03d --- /dev/null +++ b/tests/baselines/reference/mappedTypes7.types @@ -0,0 +1,38 @@ +=== tests/cases/conformance/types/mapped/mappedTypes7.ts === +interface I { + a: number; +>a : number + + b: number; +>b : number +} +type J = { +>J : J + + [K in 'b' | 'a']: I[K] +}; + +type L = Pick +>L : Pick + +declare const j: J; +>j : J + +j.a; +>j.a : number +>j : J +>a : number + +j.b; +>j.b : number +>j : J +>b : number + +declare const l: L +>l : Pick + +l.a +>l.a : number +>l : Pick +>a : number + diff --git a/tests/cases/conformance/types/mapped/mappedTypes7.ts b/tests/cases/conformance/types/mapped/mappedTypes7.ts new file mode 100644 index 0000000000000..afadb532e22f2 --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypes7.ts @@ -0,0 +1,16 @@ +interface I { + a: number; + b: number; +} +type J = { + [K in 'b' | 'a']: I[K] +}; + +type L = Pick + +declare const j: J; +j.a; +j.b; + +declare const l: L +l.a