Skip to content

Commit a40b08d

Browse files
authored
Merge pull request #30944 from Microsoft/fixInferenceToMappedType
Fix inference from enum object type to generic mapped type
2 parents 4420d10 + 50fdecc commit a40b08d

5 files changed

+69
-6
lines changed

src/compiler/checker.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15021,12 +15021,11 @@ namespace ts {
1502115021
}
1502215022
// If no inferences can be made to K's constraint, infer from a union of the property types
1502315023
// in the source to the template type X.
15024-
const valueTypes = compact([
15025-
getIndexTypeOfType(source, IndexKind.String),
15026-
getIndexTypeOfType(source, IndexKind.Number),
15027-
...map(getPropertiesOfType(source), getTypeOfSymbol)
15028-
]);
15029-
inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(target));
15024+
const propTypes = map(getPropertiesOfType(source), getTypeOfSymbol);
15025+
const stringIndexType = getIndexTypeOfType(source, IndexKind.String);
15026+
const numberIndexInfo = getNonEnumNumberIndexInfo(source);
15027+
const numberIndexType = numberIndexInfo && numberIndexInfo.type;
15028+
inferFromTypes(getUnionType(append(append(propTypes, stringIndexType), numberIndexType)), getTemplateTypeFromMappedType(target));
1503015029
return true;
1503115030
}
1503215031
return false;

tests/baselines/reference/mappedToToIndexSignatureInference.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,21 @@
22
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
33
declare const a: { [index: string]: number };
44
fn(a);
5+
6+
// Repro from #30218
7+
8+
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
9+
10+
enum E { A = 'foo', B = 'bar' }
11+
12+
let x: E[] = enumValues(E);
513

614

715
//// [mappedToToIndexSignatureInference.js]
816
fn(a);
17+
var E;
18+
(function (E) {
19+
E["A"] = "foo";
20+
E["B"] = "bar";
21+
})(E || (E = {}));
22+
var x = enumValues(E);

tests/baselines/reference/mappedToToIndexSignatureInference.symbols

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,26 @@ fn(a);
1616
>fn : Symbol(fn, Decl(mappedToToIndexSignatureInference.ts, 0, 13))
1717
>a : Symbol(a, Decl(mappedToToIndexSignatureInference.ts, 1, 13))
1818

19+
// Repro from #30218
20+
21+
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
22+
>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6))
23+
>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28))
24+
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45))
25+
>e : Symbol(e, Decl(mappedToToIndexSignatureInference.ts, 6, 64))
26+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
27+
>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 6, 28))
28+
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45))
29+
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 6, 45))
30+
31+
enum E { A = 'foo', B = 'bar' }
32+
>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86))
33+
>A : Symbol(E.A, Decl(mappedToToIndexSignatureInference.ts, 8, 8))
34+
>B : Symbol(E.B, Decl(mappedToToIndexSignatureInference.ts, 8, 19))
35+
36+
let x: E[] = enumValues(E);
37+
>x : Symbol(x, Decl(mappedToToIndexSignatureInference.ts, 10, 3))
38+
>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86))
39+
>enumValues : Symbol(enumValues, Decl(mappedToToIndexSignatureInference.ts, 2, 6))
40+
>E : Symbol(E, Decl(mappedToToIndexSignatureInference.ts, 6, 86))
41+

tests/baselines/reference/mappedToToIndexSignatureInference.types

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,22 @@ fn(a);
1212
>fn : <K extends string, V>(object: { [Key in K]: V; }) => object
1313
>a : { [index: string]: number; }
1414

15+
// Repro from #30218
16+
17+
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
18+
>enumValues : <K extends string, V extends string>(e: Record<K, V>) => V[]
19+
>e : Record<K, V>
20+
21+
enum E { A = 'foo', B = 'bar' }
22+
>E : E
23+
>A : E.A
24+
>'foo' : "foo"
25+
>B : E.B
26+
>'bar' : "bar"
27+
28+
let x: E[] = enumValues(E);
29+
>x : E[]
30+
>enumValues(E) : E[]
31+
>enumValues : <K extends string, V extends string>(e: Record<K, V>) => V[]
32+
>E : typeof E
33+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
11
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
22
declare const a: { [index: string]: number };
33
fn(a);
4+
5+
// Repro from #30218
6+
7+
declare function enumValues<K extends string, V extends string>(e: Record<K, V>): V[];
8+
9+
enum E { A = 'foo', B = 'bar' }
10+
11+
let x: E[] = enumValues(E);

0 commit comments

Comments
 (0)