Skip to content

Commit 049618f

Browse files
authored
Get contextual type of yield from contextual signature of containing function (microsoft#32433)
* Get contextual type of yield from contextual signature of containing function * Add missing baseline
1 parent b589020 commit 049618f

14 files changed

+126
-24
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24740,6 +24740,12 @@ namespace ts {
2474024740
|| anyType;
2474124741
}
2474224742

24743+
const contextualReturnType = getContextualReturnType(func);
24744+
if (contextualReturnType) {
24745+
return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, contextualReturnType, isAsync)
24746+
|| anyType;
24747+
}
24748+
2474324749
return anyType;
2474424750
}
2474524751

tests/baselines/reference/generatorTypeCheck25.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@ var g3: () => Iterable<Foo> = function* () {
1717
>function* () { yield; yield new Bar; yield new Baz; yield *[new Bar]; yield *[new Baz];} : () => Generator<Bar | Baz, void, undefined>
1818

1919
yield;
20-
>yield : any
20+
>yield : undefined
2121

2222
yield new Bar;
23-
>yield new Bar : any
23+
>yield new Bar : undefined
2424
>new Bar : Bar
2525
>Bar : typeof Bar
2626

2727
yield new Baz;
28-
>yield new Baz : any
28+
>yield new Baz : undefined
2929
>new Baz : Baz
3030
>Baz : typeof Baz
3131

tests/baselines/reference/generatorTypeCheck28.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ function* g(): IterableIterator<(x: string) => number> {
1414
>iterator : symbol
1515

1616
yield x => x.length;
17-
>yield x => x.length : any
17+
>yield x => x.length : undefined
1818
>x => x.length : (x: string) => number
1919
>x : string
2020
>x.length : number

tests/baselines/reference/generatorTypeCheck45.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ foo("", function* () { yield x => x.length }, p => undefined); // T is fixed, sh
1212
>foo : <T, U>(x: T, fun: () => Iterator<(x: T) => U, any, undefined>, fun2: (y: U) => T) => T
1313
>"" : ""
1414
>function* () { yield x => x.length } : () => Generator<(x: string) => number, void, unknown>
15-
>yield x => x.length : any
15+
>yield x => x.length : undefined
1616
>x => x.length : (x: string) => number
1717
>x : string
1818
>x.length : number

tests/baselines/reference/generatorTypeCheck46.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ foo("", function* () {
2424
>iterator : symbol
2525

2626
yield x => x.length
27-
>yield x => x.length : any
27+
>yield x => x.length : undefined
2828
>x => x.length : (x: string) => number
2929
>x : string
3030
>x.length : number

tests/baselines/reference/generatorTypeCheck62.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function strategy<T extends StrategicState>(stratName: string, gen: (a: T
3232
>stratName : string
3333
}
3434
yield next;
35-
>yield next : any
35+
>yield next : undefined
3636
>next : T
3737
}
3838
}
@@ -70,7 +70,7 @@ export const Nothing2: Strategy<State> = strategy("Nothing", function*(state: St
7070
>state : State
7171

7272
yield state;
73-
>yield state : any
73+
>yield state : undefined
7474
>state : State
7575

7676
});
@@ -84,7 +84,7 @@ export const Nothing3: Strategy<State> = strategy("Nothing", function* (state: S
8484
>state : State
8585

8686
yield ;
87-
>yield : any
87+
>yield : undefined
8888

8989
return state;
9090
>state : State

tests/baselines/reference/generatorTypeCheck63.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ export function strategy<T extends StrategicState>(stratName: string, gen: (a: T
3232
>stratName : string
3333
}
3434
yield next;
35-
>yield next : any
35+
>yield next : undefined
3636
>next : T
3737
}
3838
}
@@ -97,7 +97,7 @@ export const Nothing3: Strategy<State> = strategy("Nothing", function* (state: S
9797
>state : State
9898

9999
yield state;
100-
>yield state : any
100+
>yield state : undefined
101101
>state : State
102102

103103
return 1;
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
=== tests/cases/conformance/generators/generatorYieldContextualType.ts ===
2+
declare function f1<T, R, S>(gen: () => Generator<R, T, S>): void;
3+
>f1 : Symbol(f1, Decl(generatorYieldContextualType.ts, 0, 0))
4+
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 0, 20))
5+
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 0, 22))
6+
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 0, 25))
7+
>gen : Symbol(gen, Decl(generatorYieldContextualType.ts, 0, 29))
8+
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
9+
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 0, 22))
10+
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 0, 20))
11+
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 0, 25))
12+
13+
f1<0, 0, 1>(function* () {
14+
>f1 : Symbol(f1, Decl(generatorYieldContextualType.ts, 0, 0))
15+
16+
const a = yield 0;
17+
>a : Symbol(a, Decl(generatorYieldContextualType.ts, 2, 6))
18+
19+
return 0;
20+
});
21+
22+
declare function f2<T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>): void;
23+
>f2 : Symbol(f2, Decl(generatorYieldContextualType.ts, 4, 3))
24+
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 6, 20))
25+
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 6, 22))
26+
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 6, 25))
27+
>gen : Symbol(gen, Decl(generatorYieldContextualType.ts, 6, 29))
28+
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
29+
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 6, 22))
30+
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 6, 20))
31+
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 6, 25))
32+
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
33+
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 6, 22))
34+
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 6, 20))
35+
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 6, 25))
36+
37+
f2<0, 0, 1>(async function* () {
38+
>f2 : Symbol(f2, Decl(generatorYieldContextualType.ts, 4, 3))
39+
40+
const a = yield 0;
41+
>a : Symbol(a, Decl(generatorYieldContextualType.ts, 8, 6))
42+
43+
return 0;
44+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
=== tests/cases/conformance/generators/generatorYieldContextualType.ts ===
2+
declare function f1<T, R, S>(gen: () => Generator<R, T, S>): void;
3+
>f1 : <T, R, S>(gen: () => Generator<R, T, S>) => void
4+
>gen : () => Generator<R, T, S>
5+
6+
f1<0, 0, 1>(function* () {
7+
>f1<0, 0, 1>(function* () { const a = yield 0; return 0;}) : void
8+
>f1 : <T, R, S>(gen: () => Generator<R, T, S>) => void
9+
>function* () { const a = yield 0; return 0;} : () => Generator<0, 0, unknown>
10+
11+
const a = yield 0;
12+
>a : 1
13+
>yield 0 : 1
14+
>0 : 0
15+
16+
return 0;
17+
>0 : 0
18+
19+
});
20+
21+
declare function f2<T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>): void;
22+
>f2 : <T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>) => void
23+
>gen : () => Generator<R, T, S> | AsyncGenerator<R, T, S>
24+
25+
f2<0, 0, 1>(async function* () {
26+
>f2<0, 0, 1>(async function* () { const a = yield 0; return 0;}) : void
27+
>f2 : <T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>) => void
28+
>async function* () { const a = yield 0; return 0;} : () => AsyncGenerator<0, 0, unknown>
29+
30+
const a = yield 0;
31+
>a : 1
32+
>yield 0 : 1
33+
>0 : 0
34+
35+
return 0;
36+
>0 : 0
37+
38+
});

tests/baselines/reference/types.asyncGenerators.es2018.1.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ const assignability1: () => AsyncIterableIterator<number> = async function * ()
7878
>async function * () { yield 1;} : () => AsyncGenerator<number, void, unknown>
7979

8080
yield 1;
81-
>yield 1 : any
81+
>yield 1 : undefined
8282
>1 : 1
8383

8484
};
@@ -87,7 +87,7 @@ const assignability2: () => AsyncIterableIterator<number> = async function * ()
8787
>async function * () { yield Promise.resolve(1);} : () => AsyncGenerator<number, void, unknown>
8888

8989
yield Promise.resolve(1);
90-
>yield Promise.resolve(1) : any
90+
>yield Promise.resolve(1) : undefined
9191
>Promise.resolve(1) : Promise<number>
9292
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
9393
>Promise : PromiseConstructor
@@ -138,7 +138,7 @@ const assignability6: () => AsyncIterable<number> = async function * () {
138138
>async function * () { yield 1;} : () => AsyncGenerator<number, void, unknown>
139139

140140
yield 1;
141-
>yield 1 : any
141+
>yield 1 : undefined
142142
>1 : 1
143143

144144
};
@@ -147,7 +147,7 @@ const assignability7: () => AsyncIterable<number> = async function * () {
147147
>async function * () { yield Promise.resolve(1);} : () => AsyncGenerator<number, void, unknown>
148148

149149
yield Promise.resolve(1);
150-
>yield Promise.resolve(1) : any
150+
>yield Promise.resolve(1) : undefined
151151
>Promise.resolve(1) : Promise<number>
152152
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
153153
>Promise : PromiseConstructor
@@ -198,7 +198,7 @@ const assignability11: () => AsyncIterator<number> = async function * () {
198198
>async function * () { yield 1;} : () => AsyncGenerator<number, void, unknown>
199199

200200
yield 1;
201-
>yield 1 : any
201+
>yield 1 : undefined
202202
>1 : 1
203203

204204
};
@@ -207,7 +207,7 @@ const assignability12: () => AsyncIterator<number> = async function * () {
207207
>async function * () { yield Promise.resolve(1);} : () => AsyncGenerator<number, void, unknown>
208208

209209
yield Promise.resolve(1);
210-
>yield Promise.resolve(1) : any
210+
>yield Promise.resolve(1) : undefined
211211
>Promise.resolve(1) : Promise<number>
212212
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
213213
>Promise : PromiseConstructor

tests/baselines/reference/types.asyncGenerators.es2018.2.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const assignability1: () => AsyncIterableIterator<number> = async function * ()
3232
>async function * () { yield "a";} : () => AsyncGenerator<string, void, unknown>
3333

3434
yield "a";
35-
>yield "a" : any
35+
>yield "a" : undefined
3636
>"a" : "a"
3737

3838
};
@@ -65,7 +65,7 @@ const assignability4: () => AsyncIterable<number> = async function * () {
6565
>async function * () { yield "a";} : () => AsyncGenerator<string, void, unknown>
6666

6767
yield "a";
68-
>yield "a" : any
68+
>yield "a" : undefined
6969
>"a" : "a"
7070

7171
};
@@ -98,7 +98,7 @@ const assignability7: () => AsyncIterator<number> = async function * () {
9898
>async function * () { yield "a";} : () => AsyncGenerator<string, void, unknown>
9999

100100
yield "a";
101-
>yield "a" : any
101+
>yield "a" : undefined
102102
>"a" : "a"
103103

104104
};

tests/baselines/reference/uniqueSymbols.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -839,15 +839,15 @@ const o3: Context = {
839839
>method3 : () => AsyncGenerator<unique symbol, void, unknown>
840840

841841
yield s; // yield type should not widen due to contextual type
842-
>yield s : any
842+
>yield s : undefined
843843
>s : unique symbol
844844

845845
},
846846
* method4() {
847847
>method4 : () => Generator<unique symbol, void, unknown>
848848

849849
yield s; // yield type should not widen due to contextual type
850-
>yield s : any
850+
>yield s : undefined
851851
>s : unique symbol
852852

853853
},

tests/baselines/reference/uniqueSymbolsDeclarations.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -832,15 +832,15 @@ const o4: Context = {
832832
>method3 : () => AsyncGenerator<unique symbol, void, unknown>
833833

834834
yield s; // yield type should not widen due to contextual type
835-
>yield s : any
835+
>yield s : undefined
836836
>s : unique symbol
837837

838838
},
839839
* method4() {
840840
>method4 : () => Generator<unique symbol, void, unknown>
841841

842842
yield s; // yield type should not widen due to contextual type
843-
>yield s : any
843+
>yield s : undefined
844844
>s : unique symbol
845845

846846
},
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @target: esnext
2+
// @strict: true
3+
// @noEmit: true
4+
declare function f1<T, R, S>(gen: () => Generator<R, T, S>): void;
5+
f1<0, 0, 1>(function* () {
6+
const a = yield 0;
7+
return 0;
8+
});
9+
10+
declare function f2<T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>): void;
11+
f2<0, 0, 1>(async function* () {
12+
const a = yield 0;
13+
return 0;
14+
});

0 commit comments

Comments
 (0)