diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 72e85b3f8a81b..5673b8b8089d4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14960,12 +14960,11 @@ namespace ts { } // If no inferences can be made to K's constraint, infer from a union of the property types // in the source to the template type X. - const valueTypes = compact([ - getIndexTypeOfType(source, IndexKind.String), - getIndexTypeOfType(source, IndexKind.Number), - ...map(getPropertiesOfType(source), getTypeOfSymbol) - ]); - inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(target)); + const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol); + const stringIndexType = getIndexTypeOfType(source, IndexKind.String); + const numberIndexInfo = getNonEnumNumberIndexInfo(source); + const numberIndexType = numberIndexInfo && numberIndexInfo.type; + inferFromTypes(getUnionType(append(append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target)); return true; } return false; diff --git a/tests/baselines/reference/mappedToToIndexSignatureInference.js b/tests/baselines/reference/mappedToToIndexSignatureInference.js index 2ea09b663a97b..03a24ab0ad98d 100644 --- a/tests/baselines/reference/mappedToToIndexSignatureInference.js +++ b/tests/baselines/reference/mappedToToIndexSignatureInference.js @@ -2,7 +2,21 @@ declare const fn: (object: { [Key in K]: V }) => object; declare const a: { [index: string]: number }; fn(a); + +// Repro from #30218 + +declare function enumValues(e: Record): V[]; + +enum E { A = 'foo', B = 'bar' } + +let x: E[] = enumValues(E); //// [mappedToToIndexSignatureInference.js] fn(a); +var E; +(function (E) { + E["A"] = "foo"; + E["B"] = "bar"; +})(E || (E = {})); +var x = enumValues(E); diff --git a/tests/baselines/reference/mappedToToIndexSignatureInference.symbols b/tests/baselines/reference/mappedToToIndexSignatureInference.symbols index d071f3f4c1cb7..d2d6f923f8706 100644 --- a/tests/baselines/reference/mappedToToIndexSignatureInference.symbols +++ b/tests/baselines/reference/mappedToToIndexSignatureInference.symbols @@ -16,3 +16,26 @@ fn(a); >fn : Symbol(fn, Decl(mappedToToIndexSignatureInference.ts, 0, 13)) >a : Symbol(a, Decl(mappedToToIndexSignatureInference.ts, 1, 13)) +// Repro from #30218 + +declare function enumValues(e: Record): V[]; +>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6)) +>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28)) +>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45)) +>e : Symbol(e, Decl(mappedToToIndexSignatureInference.ts, 6, 64)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28)) +>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45)) +>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45)) + +enum E { A = 'foo', B = 'bar' } +>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86)) +>A : Symbol(E.A, Decl(mappedToToIndexSignatureInference.ts, 8, 8)) +>B : Symbol(E.B, Decl(mappedToToIndexSignatureInference.ts, 8, 19)) + +let x: E[] = enumValues(E); +>x : Symbol(x, Decl(mappedToToIndexSignatureInference.ts, 10, 3)) +>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86)) +>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6)) +>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86)) + diff --git a/tests/baselines/reference/mappedToToIndexSignatureInference.types b/tests/baselines/reference/mappedToToIndexSignatureInference.types index 35b9b3565e009..21ab79e8e48b9 100644 --- a/tests/baselines/reference/mappedToToIndexSignatureInference.types +++ b/tests/baselines/reference/mappedToToIndexSignatureInference.types @@ -12,3 +12,22 @@ fn(a); >fn : (object: { [Key in K]: V; }) => object >a : { [index: string]: number; } +// Repro from #30218 + +declare function enumValues(e: Record): V[]; +>enumValues : (e: Record) => V[] +>e : Record + +enum E { A = 'foo', B = 'bar' } +>E : E +>A : E.A +>'foo' : "foo" +>B : E.B +>'bar' : "bar" + +let x: E[] = enumValues(E); +>x : E[] +>enumValues(E) : E[] +>enumValues : (e: Record) => V[] +>E : typeof E + diff --git a/tests/cases/compiler/mappedToToIndexSignatureInference.ts b/tests/cases/compiler/mappedToToIndexSignatureInference.ts index 6ce63ead59cb0..ee6f71a06166a 100644 --- a/tests/cases/compiler/mappedToToIndexSignatureInference.ts +++ b/tests/cases/compiler/mappedToToIndexSignatureInference.ts @@ -1,3 +1,11 @@ declare const fn: (object: { [Key in K]: V }) => object; declare const a: { [index: string]: number }; fn(a); + +// Repro from #30218 + +declare function enumValues(e: Record): V[]; + +enum E { A = 'foo', B = 'bar' } + +let x: E[] = enumValues(E);