Skip to content

Get contextual type of yield from contextual signature of containing function #32433

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24740,6 +24740,12 @@ namespace ts {
|| anyType;
}

const contextualReturnType = getContextualReturnType(func);
if (contextualReturnType) {
return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, contextualReturnType, isAsync)
|| anyType;
}

return anyType;
}

Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/generatorTypeCheck25.types
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ var g3: () => Iterable<Foo> = function* () {
>function* () { yield; yield new Bar; yield new Baz; yield *[new Bar]; yield *[new Baz];} : () => Generator<Bar | Baz, void, undefined>

yield;
>yield : any
>yield : undefined

yield new Bar;
>yield new Bar : any
>yield new Bar : undefined
>new Bar : Bar
>Bar : typeof Bar

yield new Baz;
>yield new Baz : any
>yield new Baz : undefined
>new Baz : Baz
>Baz : typeof Baz

Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/generatorTypeCheck28.types
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function* g(): IterableIterator<(x: string) => number> {
>iterator : symbol

yield x => x.length;
>yield x => x.length : any
>yield x => x.length : undefined
>x => x.length : (x: string) => number
>x : string
>x.length : number
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/generatorTypeCheck45.types
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ foo("", function* () { yield x => x.length }, p => undefined); // T is fixed, sh
>foo : <T, U>(x: T, fun: () => Iterator<(x: T) => U, any, undefined>, fun2: (y: U) => T) => T
>"" : ""
>function* () { yield x => x.length } : () => Generator<(x: string) => number, void, unknown>
>yield x => x.length : any
>yield x => x.length : undefined
>x => x.length : (x: string) => number
>x : string
>x.length : number
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/generatorTypeCheck46.types
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ foo("", function* () {
>iterator : symbol

yield x => x.length
>yield x => x.length : any
>yield x => x.length : undefined
>x => x.length : (x: string) => number
>x : string
>x.length : number
Expand Down
6 changes: 3 additions & 3 deletions tests/baselines/reference/generatorTypeCheck62.types
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function strategy<T extends StrategicState>(stratName: string, gen: (a: T
>stratName : string
}
yield next;
>yield next : any
>yield next : undefined
>next : T
}
}
Expand Down Expand Up @@ -70,7 +70,7 @@ export const Nothing2: Strategy<State> = strategy("Nothing", function*(state: St
>state : State

yield state;
>yield state : any
>yield state : undefined
>state : State

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

yield ;
>yield : any
>yield : undefined

return state;
>state : State
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/generatorTypeCheck63.types
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function strategy<T extends StrategicState>(stratName: string, gen: (a: T
>stratName : string
}
yield next;
>yield next : any
>yield next : undefined
>next : T
}
}
Expand Down Expand Up @@ -97,7 +97,7 @@ export const Nothing3: Strategy<State> = strategy("Nothing", function* (state: S
>state : State

yield state;
>yield state : any
>yield state : undefined
>state : State

return 1;
Expand Down
44 changes: 44 additions & 0 deletions tests/baselines/reference/generatorYieldContextualType.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
=== tests/cases/conformance/generators/generatorYieldContextualType.ts ===
declare function f1<T, R, S>(gen: () => Generator<R, T, S>): void;
>f1 : Symbol(f1, Decl(generatorYieldContextualType.ts, 0, 0))
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 0, 20))
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 0, 22))
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 0, 25))
>gen : Symbol(gen, Decl(generatorYieldContextualType.ts, 0, 29))
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 0, 22))
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 0, 20))
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 0, 25))

f1<0, 0, 1>(function* () {
>f1 : Symbol(f1, Decl(generatorYieldContextualType.ts, 0, 0))

const a = yield 0;
>a : Symbol(a, Decl(generatorYieldContextualType.ts, 2, 6))

return 0;
});

declare function f2<T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>): void;
>f2 : Symbol(f2, Decl(generatorYieldContextualType.ts, 4, 3))
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 6, 20))
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 6, 22))
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 6, 25))
>gen : Symbol(gen, Decl(generatorYieldContextualType.ts, 6, 29))
>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --))
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 6, 22))
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 6, 20))
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 6, 25))
>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --))
>R : Symbol(R, Decl(generatorYieldContextualType.ts, 6, 22))
>T : Symbol(T, Decl(generatorYieldContextualType.ts, 6, 20))
>S : Symbol(S, Decl(generatorYieldContextualType.ts, 6, 25))

f2<0, 0, 1>(async function* () {
>f2 : Symbol(f2, Decl(generatorYieldContextualType.ts, 4, 3))

const a = yield 0;
>a : Symbol(a, Decl(generatorYieldContextualType.ts, 8, 6))

return 0;
});
38 changes: 38 additions & 0 deletions tests/baselines/reference/generatorYieldContextualType.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
=== tests/cases/conformance/generators/generatorYieldContextualType.ts ===
declare function f1<T, R, S>(gen: () => Generator<R, T, S>): void;
>f1 : <T, R, S>(gen: () => Generator<R, T, S>) => void
>gen : () => Generator<R, T, S>

f1<0, 0, 1>(function* () {
>f1<0, 0, 1>(function* () { const a = yield 0; return 0;}) : void
>f1 : <T, R, S>(gen: () => Generator<R, T, S>) => void
>function* () { const a = yield 0; return 0;} : () => Generator<0, 0, unknown>

const a = yield 0;
>a : 1
>yield 0 : 1
>0 : 0

return 0;
>0 : 0

});

declare function f2<T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>): void;
>f2 : <T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>) => void
>gen : () => Generator<R, T, S> | AsyncGenerator<R, T, S>

f2<0, 0, 1>(async function* () {
>f2<0, 0, 1>(async function* () { const a = yield 0; return 0;}) : void
>f2 : <T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>) => void
>async function* () { const a = yield 0; return 0;} : () => AsyncGenerator<0, 0, unknown>

const a = yield 0;
>a : 1
>yield 0 : 1
>0 : 0

return 0;
>0 : 0

});
12 changes: 6 additions & 6 deletions tests/baselines/reference/types.asyncGenerators.es2018.1.types
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const assignability1: () => AsyncIterableIterator<number> = async function * ()
>async function * () { yield 1;} : () => AsyncGenerator<number, void, unknown>

yield 1;
>yield 1 : any
>yield 1 : undefined
>1 : 1

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

yield Promise.resolve(1);
>yield Promise.resolve(1) : any
>yield Promise.resolve(1) : undefined
>Promise.resolve(1) : Promise<number>
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
>Promise : PromiseConstructor
Expand Down Expand Up @@ -138,7 +138,7 @@ const assignability6: () => AsyncIterable<number> = async function * () {
>async function * () { yield 1;} : () => AsyncGenerator<number, void, unknown>

yield 1;
>yield 1 : any
>yield 1 : undefined
>1 : 1

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

yield Promise.resolve(1);
>yield Promise.resolve(1) : any
>yield Promise.resolve(1) : undefined
>Promise.resolve(1) : Promise<number>
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
>Promise : PromiseConstructor
Expand Down Expand Up @@ -198,7 +198,7 @@ const assignability11: () => AsyncIterator<number> = async function * () {
>async function * () { yield 1;} : () => AsyncGenerator<number, void, unknown>

yield 1;
>yield 1 : any
>yield 1 : undefined
>1 : 1

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

yield Promise.resolve(1);
>yield Promise.resolve(1) : any
>yield Promise.resolve(1) : undefined
>Promise.resolve(1) : Promise<number>
>Promise.resolve : { <T>(value: T | PromiseLike<T>): Promise<T>; (): Promise<void>; }
>Promise : PromiseConstructor
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ const assignability1: () => AsyncIterableIterator<number> = async function * ()
>async function * () { yield "a";} : () => AsyncGenerator<string, void, unknown>

yield "a";
>yield "a" : any
>yield "a" : undefined
>"a" : "a"

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

yield "a";
>yield "a" : any
>yield "a" : undefined
>"a" : "a"

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

yield "a";
>yield "a" : any
>yield "a" : undefined
>"a" : "a"

};
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/uniqueSymbols.types
Original file line number Diff line number Diff line change
Expand Up @@ -839,15 +839,15 @@ const o3: Context = {
>method3 : () => AsyncGenerator<unique symbol, void, unknown>

yield s; // yield type should not widen due to contextual type
>yield s : any
>yield s : undefined
>s : unique symbol

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

yield s; // yield type should not widen due to contextual type
>yield s : any
>yield s : undefined
>s : unique symbol

},
Expand Down
4 changes: 2 additions & 2 deletions tests/baselines/reference/uniqueSymbolsDeclarations.types
Original file line number Diff line number Diff line change
Expand Up @@ -832,15 +832,15 @@ const o4: Context = {
>method3 : () => AsyncGenerator<unique symbol, void, unknown>

yield s; // yield type should not widen due to contextual type
>yield s : any
>yield s : undefined
>s : unique symbol

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

yield s; // yield type should not widen due to contextual type
>yield s : any
>yield s : undefined
>s : unique symbol

},
Expand Down
14 changes: 14 additions & 0 deletions tests/cases/conformance/generators/generatorYieldContextualType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// @target: esnext
// @strict: true
// @noEmit: true
declare function f1<T, R, S>(gen: () => Generator<R, T, S>): void;
f1<0, 0, 1>(function* () {
const a = yield 0;
return 0;
});

declare function f2<T, R, S>(gen: () => Generator<R, T, S> | AsyncGenerator<R, T, S>): void;
f2<0, 0, 1>(async function* () {
const a = yield 0;
return 0;
});