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

* Get contextual type of yield from contextual signature of containing function

* Add missing baseline
This commit is contained in:
Ron Buckton
2019-07-16 17:16:21 -07:00
committed by GitHub
parent b589020bb3
commit 049618f7da
14 changed files with 126 additions and 24 deletions
+6
View File
@@ -24740,6 +24740,12 @@ namespace ts {
|| anyType;
}
const contextualReturnType = getContextualReturnType(func);
if (contextualReturnType) {
return getIterationTypeOfGeneratorFunctionReturnType(IterationTypeKind.Next, contextualReturnType, isAsync)
|| anyType;
}
return anyType;
}
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
}
}
@@ -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
});
@@ -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
@@ -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
}
}
@@ -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;
@@ -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;
});
@@ -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
});
@@ -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
};
@@ -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
@@ -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
};
@@ -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
@@ -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
};
@@ -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
@@ -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"
};
@@ -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"
};
@@ -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"
};
@@ -839,7 +839,7 @@ 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
},
@@ -847,7 +847,7 @@ const o3: Context = {
>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
},
@@ -832,7 +832,7 @@ 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
},
@@ -840,7 +840,7 @@ const o4: Context = {
>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
},
@@ -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;
});