Skip to content

Commit c0729a2

Browse files
committed
Use string/number signature to get contextual type
Fixes #26587
1 parent 4d504f9 commit c0729a2

13 files changed

+76
-106
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16708,6 +16708,8 @@ namespace ts {
1670816708
return restType;
1670916709
}
1671016710
}
16711+
return isNumericLiteralName(name) && getIndexTypeOfContextualType(type, IndexKind.Number) ||
16712+
getIndexTypeOfContextualType(type, IndexKind.String);
1671116713
}
1671216714
return undefined;
1671316715
}, /*noReductions*/ true);

tests/baselines/reference/contextualTypeWithUnionTypeIndexSignatures.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ interface IWithNumberIndexSignature2 {
3939
// If S is not empty, U has a string index signature of a union type of
4040
// the types of the string index signatures from each type in S.
4141
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { z: a => a }; // a should be number
42-
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be any
42+
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be number (because of index signature of IWithStringIndexSignature1)
4343
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: "hello" };
4444
var x2: IWithStringIndexSignature1 | IWithStringIndexSignature2 = { z: a => a.toString() }; // a should be number
4545
var x2: IWithStringIndexSignature1 | IWithStringIndexSignature2 = { z: a => a }; // a should be number
@@ -49,7 +49,7 @@ var x2: IWithStringIndexSignature1 | IWithStringIndexSignature2 = { z: a => a };
4949
// If S is not empty, U has a numeric index signature of a union type of
5050
// the types of the numeric index signatures from each type in S.
5151
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 1: a => a }; // a should be number
52-
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be any
52+
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be number (because of index signature of IWithNumberIndexSignature1)
5353
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: "hello" };
5454
var x4: IWithNumberIndexSignature1 | IWithNumberIndexSignature2 = { 1: a => a.toString() }; // a should be number
5555
var x4: IWithNumberIndexSignature1 | IWithNumberIndexSignature2 = { 1: a => a }; // a should be number
@@ -66,15 +66,15 @@ var x4: IWithNumberIndexSignature1 | IWithNumberIndexSignature2 = { 1: a => a };
6666
// If S is not empty, U has a string index signature of a union type of
6767
// the types of the string index signatures from each type in S.
6868
var x = { z: function (a) { return a; } }; // a should be number
69-
var x = { foo: function (a) { return a; } }; // a should be any
69+
var x = { foo: function (a) { return a; } }; // a should be number (because of index signature of IWithStringIndexSignature1)
7070
var x = { foo: "hello" };
7171
var x2 = { z: function (a) { return a.toString(); } }; // a should be number
7272
var x2 = { z: function (a) { return a; } }; // a should be number
7373
// Let S be the set of types in U that has a numeric index signature.
7474
// If S is not empty, U has a numeric index signature of a union type of
7575
// the types of the numeric index signatures from each type in S.
7676
var x3 = { 1: function (a) { return a; } }; // a should be number
77-
var x3 = { 0: function (a) { return a; } }; // a should be any
77+
var x3 = { 0: function (a) { return a; } }; // a should be number (because of index signature of IWithNumberIndexSignature1)
7878
var x3 = { 0: "hello" };
7979
var x4 = { 1: function (a) { return a.toString(); } }; // a should be number
8080
var x4 = { 1: function (a) { return a; } }; // a should be number

tests/baselines/reference/contextualTypeWithUnionTypeIndexSignatures.symbols

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { z: a => a };
7474
>a : Symbol(a, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 39, 70))
7575
>a : Symbol(a, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 39, 70))
7676

77-
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be any
77+
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be number (because of index signature of IWithStringIndexSignature1)
7878
>x : Symbol(x, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 39, 3), Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 40, 3), Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 41, 3))
7979
>IWithNoStringIndexSignature : Symbol(IWithNoStringIndexSignature, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 7, 1))
8080
>IWithStringIndexSignature1 : Symbol(IWithStringIndexSignature1, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 14, 1))
@@ -118,7 +118,7 @@ var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 1: a => a }
118118
>a : Symbol(a, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 49, 71))
119119
>a : Symbol(a, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 49, 71))
120120

121-
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be any
121+
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be number (because of index signature of IWithNumberIndexSignature1)
122122
>x3 : Symbol(x3, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 49, 3), Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 50, 3), Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 51, 3))
123123
>IWithNoNumberIndexSignature : Symbol(IWithNoNumberIndexSignature, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 11, 1))
124124
>IWithNumberIndexSignature1 : Symbol(IWithNumberIndexSignature1, Decl(contextualTypeWithUnionTypeIndexSignatures.ts, 20, 1))

tests/baselines/reference/contextualTypeWithUnionTypeIndexSignatures.types

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { z: a => a };
5454
>a : number
5555
>a : number
5656

57-
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be any
57+
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be number (because of index signature of IWithStringIndexSignature1)
5858
>x : IWithNoStringIndexSignature | IWithStringIndexSignature1
59-
>{ foo: a => a } : { foo: (a: any) => any; }
60-
>foo : (a: any) => any
61-
>a => a : (a: any) => any
62-
>a : any
63-
>a : any
59+
>{ foo: a => a } : { foo: (a: number) => number; }
60+
>foo : (a: number) => number
61+
>a => a : (a: number) => number
62+
>a : number
63+
>a : number
6464

6565
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: "hello" };
6666
>x : IWithNoStringIndexSignature | IWithStringIndexSignature1
@@ -99,13 +99,13 @@ var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 1: a => a }
9999
>a : number
100100
>a : number
101101

102-
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be any
102+
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be number (because of index signature of IWithNumberIndexSignature1)
103103
>x3 : IWithNoNumberIndexSignature | IWithNumberIndexSignature1
104-
>{ 0: a => a } : { 0: (a: any) => any; }
105-
>0 : (a: any) => any
106-
>a => a : (a: any) => any
107-
>a : any
108-
>a : any
104+
>{ 0: a => a } : { 0: (a: number) => number; }
105+
>0 : (a: number) => number
106+
>a => a : (a: number) => number
107+
>a : number
108+
>a : number
109109

110110
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: "hello" };
111111
>x3 : IWithNoNumberIndexSignature | IWithNumberIndexSignature1

tests/baselines/reference/contextualTypingOfOptionalMembers.errors.txt

Lines changed: 0 additions & 80 deletions
This file was deleted.

tests/baselines/reference/contextualTypingOfOptionalMembers.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,8 +183,8 @@ const a = <App4 state={100} foo={s => s} />; // TODO: should be number => number
183183
>App4 : <State, Actions extends ActionsObjectOr<State>>(props: (string & { state: State; }) | (Actions & { state: State; })) => JSX.Element
184184
>state : number
185185
>100 : 100
186-
>foo : (s: any) => any
187-
>s => s : (s: any) => any
188-
>s : any
189-
>s : any
186+
>foo : (s: number) => number
187+
>s => s : (s: number) => number
188+
>s : number
189+
>s : number
190190

tests/baselines/reference/narrowingByTypeofInSwitch.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -543,7 +543,7 @@ function multipleGenericFuse<X extends L | number, Y extends R | number>(xy: X |
543543

544544
case 'function': return [xy, 1];
545545
>'function' : "function"
546-
>[xy, 1] : [X, number]
546+
>[xy, 1] : [X, 1]
547547
>xy : X
548548
>1 : 1
549549

tests/baselines/reference/tsxAttributeResolution10.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export class MyComponent {
3535
<MyComponent bar={true} />;
3636
><MyComponent bar={true} /> : JSX.Element
3737
>MyComponent : typeof MyComponent
38-
>bar : boolean
38+
>bar : true
3939
>true : true
4040

4141
// Should be ok
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//// [unionTypeWithIndexedLiteralType.ts]
2+
interface I { x: number; }
3+
interface Idx { [index: string]: U; }
4+
type U = Idx | I | "lit";
5+
const u: U = { x: "lit" };
6+
7+
//// [unionTypeWithIndexedLiteralType.js]
8+
var u = { x: "lit" };
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
=== tests/cases/compiler/unionTypeWithIndexedLiteralType.ts ===
2+
interface I { x: number; }
3+
>I : Symbol(I, Decl(unionTypeWithIndexedLiteralType.ts, 0, 0))
4+
>x : Symbol(I.x, Decl(unionTypeWithIndexedLiteralType.ts, 0, 13))
5+
6+
interface Idx { [index: string]: U; }
7+
>Idx : Symbol(Idx, Decl(unionTypeWithIndexedLiteralType.ts, 0, 26))
8+
>index : Symbol(index, Decl(unionTypeWithIndexedLiteralType.ts, 1, 17))
9+
>U : Symbol(U, Decl(unionTypeWithIndexedLiteralType.ts, 1, 37))
10+
11+
type U = Idx | I | "lit";
12+
>U : Symbol(U, Decl(unionTypeWithIndexedLiteralType.ts, 1, 37))
13+
>Idx : Symbol(Idx, Decl(unionTypeWithIndexedLiteralType.ts, 0, 26))
14+
>I : Symbol(I, Decl(unionTypeWithIndexedLiteralType.ts, 0, 0))
15+
16+
const u: U = { x: "lit" };
17+
>u : Symbol(u, Decl(unionTypeWithIndexedLiteralType.ts, 3, 5))
18+
>U : Symbol(U, Decl(unionTypeWithIndexedLiteralType.ts, 1, 37))
19+
>x : Symbol(x, Decl(unionTypeWithIndexedLiteralType.ts, 3, 14))
20+
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
=== tests/cases/compiler/unionTypeWithIndexedLiteralType.ts ===
2+
interface I { x: number; }
3+
>x : number
4+
5+
interface Idx { [index: string]: U; }
6+
>index : string
7+
8+
type U = Idx | I | "lit";
9+
>U : U
10+
11+
const u: U = { x: "lit" };
12+
>u : U
13+
>{ x: "lit" } : { x: "lit"; }
14+
>x : "lit"
15+
>"lit" : "lit"
16+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
interface I { x: number; }
2+
interface Idx { [index: string]: U; }
3+
type U = Idx | I | "lit";
4+
const u: U = { x: "lit" };

tests/cases/conformance/types/union/contextualTypeWithUnionTypeIndexSignatures.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ interface IWithNumberIndexSignature2 {
3838
// If S is not empty, U has a string index signature of a union type of
3939
// the types of the string index signatures from each type in S.
4040
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { z: a => a }; // a should be number
41-
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be any
41+
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: a => a }; // a should be number (because of index signature of IWithStringIndexSignature1)
4242
var x: IWithNoStringIndexSignature | IWithStringIndexSignature1 = { foo: "hello" };
4343
var x2: IWithStringIndexSignature1 | IWithStringIndexSignature2 = { z: a => a.toString() }; // a should be number
4444
var x2: IWithStringIndexSignature1 | IWithStringIndexSignature2 = { z: a => a }; // a should be number
@@ -48,7 +48,7 @@ var x2: IWithStringIndexSignature1 | IWithStringIndexSignature2 = { z: a => a };
4848
// If S is not empty, U has a numeric index signature of a union type of
4949
// the types of the numeric index signatures from each type in S.
5050
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 1: a => a }; // a should be number
51-
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be any
51+
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: a => a }; // a should be number (because of index signature of IWithNumberIndexSignature1)
5252
var x3: IWithNoNumberIndexSignature | IWithNumberIndexSignature1 = { 0: "hello" };
5353
var x4: IWithNumberIndexSignature1 | IWithNumberIndexSignature2 = { 1: a => a.toString() }; // a should be number
5454
var x4: IWithNumberIndexSignature1 | IWithNumberIndexSignature2 = { 1: a => a }; // a should be number

0 commit comments

Comments
 (0)