diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9dfb4a7e112c2..4822e2129ae59 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -24315,7 +24315,7 @@ namespace ts { } function getCandidateDiscriminantPropertyAccess(expr: Expression) { - if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference)) { + if (isBindingPattern(reference) || isFunctionExpressionOrArrowFunction(reference) || isObjectLiteralMethod(reference)) { // When the reference is a binding pattern or function or arrow expression, we are narrowing a pesudo-reference in // getNarrowedTypeOfSymbol. An identifier for a destructuring variable declared in the same binding pattern or // parameter declared in the same parameter list is a candidate. diff --git a/tests/baselines/reference/dependentDestructuredVariables.js b/tests/baselines/reference/dependentDestructuredVariables.js index 2eb7be3d946a4..db312d66704fd 100644 --- a/tests/baselines/reference/dependentDestructuredVariables.js +++ b/tests/baselines/reference/dependentDestructuredVariables.js @@ -225,10 +225,101 @@ const reducer: (...args: ReducerArgs) => void = (op, args) => { reducer("add", { a: 1, b: 3 }); reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] }); + +// repro from https://github.com/microsoft/TypeScript/pull/47190#issuecomment-1057603588 + +type FooMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): void; +} + +let fooM: FooMethod = { + method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +}; + +type FooAsyncMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): Promise; +} + +let fooAsyncM: FooAsyncMethod = { + async method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +}; + +type FooGenMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): Generator; +} + +let fooGenM: FooGenMethod = { + *method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +}; + +type FooAsyncGenMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): AsyncGenerator; +} + +let fooAsyncGenM: FooAsyncGenMethod = { + async *method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +}; //// [dependentDestructuredVariables.js] "use strict"; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } +var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +}; function f10({ kind, payload }) { if (kind === 'A') { payload.toFixed(); @@ -394,6 +485,50 @@ const reducer = (op, args) => { }; reducer("add", { a: 1, b: 3 }); reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] }); +let fooM = { + method(type, cb) { + if (type == 'num') { + cb(123); + } + else { + cb("abc"); + } + } +}; +let fooAsyncM = { + method(type, cb) { + return __awaiter(this, void 0, void 0, function* () { + if (type == 'num') { + cb(123); + } + else { + cb("abc"); + } + }); + } +}; +let fooGenM = { + *method(type, cb) { + if (type == 'num') { + cb(123); + } + else { + cb("abc"); + } + } +}; +let fooAsyncGenM = { + method(type, cb) { + return __asyncGenerator(this, arguments, function* method_1() { + if (type == 'num') { + cb(123); + } + else { + cb("abc"); + } + }); + } +}; //// [dependentDestructuredVariables.d.ts] @@ -469,3 +604,43 @@ declare type ReducerArgs = ["add", { secondArr: any[]; }]; declare const reducer: (...args: ReducerArgs) => void; +declare type FooMethod = { + method(...args: [ + type: "str", + cb: (e: string) => void + ] | [ + type: "num", + cb: (e: number) => void + ]): void; +}; +declare let fooM: FooMethod; +declare type FooAsyncMethod = { + method(...args: [ + type: "str", + cb: (e: string) => void + ] | [ + type: "num", + cb: (e: number) => void + ]): Promise; +}; +declare let fooAsyncM: FooAsyncMethod; +declare type FooGenMethod = { + method(...args: [ + type: "str", + cb: (e: string) => void + ] | [ + type: "num", + cb: (e: number) => void + ]): Generator; +}; +declare let fooGenM: FooGenMethod; +declare type FooAsyncGenMethod = { + method(...args: [ + type: "str", + cb: (e: string) => void + ] | [ + type: "num", + cb: (e: number) => void + ]): AsyncGenerator; +}; +declare let fooAsyncGenM: FooAsyncGenMethod; diff --git a/tests/baselines/reference/dependentDestructuredVariables.symbols b/tests/baselines/reference/dependentDestructuredVariables.symbols index bad7fbf5b690e..af1919fc31226 100644 --- a/tests/baselines/reference/dependentDestructuredVariables.symbols +++ b/tests/baselines/reference/dependentDestructuredVariables.symbols @@ -321,7 +321,7 @@ interface B { variant: 'b', value: Array } >T : Symbol(T, Decl(dependentDestructuredVariables.ts, 128, 12)) >variant : Symbol(B.variant, Decl(dependentDestructuredVariables.ts, 128, 16)) >value : Symbol(B.value, Decl(dependentDestructuredVariables.ts, 128, 30)) ->Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 3 more) >T : Symbol(T, Decl(dependentDestructuredVariables.ts, 128, 12)) type AB = A | B; @@ -342,7 +342,7 @@ declare function printValueList(t: Array): void; >printValueList : Symbol(printValueList, Decl(dependentDestructuredVariables.ts, 132, 43)) >T : Symbol(T, Decl(dependentDestructuredVariables.ts, 134, 32)) >t : Symbol(t, Decl(dependentDestructuredVariables.ts, 134, 35)) ->Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --) ... and 3 more) >T : Symbol(T, Decl(dependentDestructuredVariables.ts, 134, 32)) function unrefined1(ab: AB): void { @@ -514,7 +514,7 @@ declare function readFile(path: string, callback: (...args: [err: null, data: un >path : Symbol(path, Decl(dependentDestructuredVariables.ts, 200, 26)) >callback : Symbol(callback, Decl(dependentDestructuredVariables.ts, 200, 39)) >args : Symbol(args, Decl(dependentDestructuredVariables.ts, 200, 51)) ->Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --)) readFile('hello', (err, data) => { >readFile : Symbol(readFile, Decl(dependentDestructuredVariables.ts, 198, 2)) @@ -595,3 +595,160 @@ reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] }); >firstArr : Symbol(firstArr, Decl(dependentDestructuredVariables.ts, 225, 19)) >secondArr : Symbol(secondArr, Decl(dependentDestructuredVariables.ts, 225, 37)) +// repro from https://github.com/microsoft/TypeScript/pull/47190#issuecomment-1057603588 + +type FooMethod = { +>FooMethod : Symbol(FooMethod, Decl(dependentDestructuredVariables.ts, 225, 59)) + + method(...args: +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 229, 18)) +>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 230, 9)) + + [type: "str", cb: (e: string) => void] | +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 231, 23)) + + [type: "num", cb: (e: number) => void] +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 232, 23)) + + ): void; +} + +let fooM: FooMethod = { +>fooM : Symbol(fooM, Decl(dependentDestructuredVariables.ts, 236, 3)) +>FooMethod : Symbol(FooMethod, Decl(dependentDestructuredVariables.ts, 225, 59)) + + method(type, cb) { +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 236, 23)) +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 237, 9)) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 237, 14)) + + if (type == 'num') { +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 237, 9)) + + cb(123) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 237, 14)) + + } else { + cb("abc") +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 237, 14)) + } + } +}; + +type FooAsyncMethod = { +>FooAsyncMethod : Symbol(FooAsyncMethod, Decl(dependentDestructuredVariables.ts, 244, 2)) + + method(...args: +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 246, 23)) +>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 247, 9)) + + [type: "str", cb: (e: string) => void] | +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 248, 23)) + + [type: "num", cb: (e: number) => void] +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 249, 23)) + + ): Promise; +>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --)) +} + +let fooAsyncM: FooAsyncMethod = { +>fooAsyncM : Symbol(fooAsyncM, Decl(dependentDestructuredVariables.ts, 253, 3)) +>FooAsyncMethod : Symbol(FooAsyncMethod, Decl(dependentDestructuredVariables.ts, 244, 2)) + + async method(type, cb) { +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 253, 33)) +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 254, 15)) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 254, 20)) + + if (type == 'num') { +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 254, 15)) + + cb(123) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 254, 20)) + + } else { + cb("abc") +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 254, 20)) + } + } +}; + +type FooGenMethod = { +>FooGenMethod : Symbol(FooGenMethod, Decl(dependentDestructuredVariables.ts, 261, 2)) + + method(...args: +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 263, 21)) +>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 264, 9)) + + [type: "str", cb: (e: string) => void] | +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 265, 23)) + + [type: "num", cb: (e: number) => void] +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 266, 23)) + + ): Generator; +>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --)) +} + +let fooGenM: FooGenMethod = { +>fooGenM : Symbol(fooGenM, Decl(dependentDestructuredVariables.ts, 270, 3)) +>FooGenMethod : Symbol(FooGenMethod, Decl(dependentDestructuredVariables.ts, 261, 2)) + + *method(type, cb) { +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 270, 29)) +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 271, 10)) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 271, 15)) + + if (type == 'num') { +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 271, 10)) + + cb(123) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 271, 15)) + + } else { + cb("abc") +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 271, 15)) + } + } +}; + +type FooAsyncGenMethod = { +>FooAsyncGenMethod : Symbol(FooAsyncGenMethod, Decl(dependentDestructuredVariables.ts, 278, 2)) + + method(...args: +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 280, 26)) +>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 281, 9)) + + [type: "str", cb: (e: string) => void] | +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 282, 23)) + + [type: "num", cb: (e: number) => void] +>e : Symbol(e, Decl(dependentDestructuredVariables.ts, 283, 23)) + + ): AsyncGenerator; +>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --)) +} + +let fooAsyncGenM: FooAsyncGenMethod = { +>fooAsyncGenM : Symbol(fooAsyncGenM, Decl(dependentDestructuredVariables.ts, 287, 3)) +>FooAsyncGenMethod : Symbol(FooAsyncGenMethod, Decl(dependentDestructuredVariables.ts, 278, 2)) + + async *method(type, cb) { +>method : Symbol(method, Decl(dependentDestructuredVariables.ts, 287, 39)) +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 288, 16)) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 288, 21)) + + if (type == 'num') { +>type : Symbol(type, Decl(dependentDestructuredVariables.ts, 288, 16)) + + cb(123) +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 288, 21)) + + } else { + cb("abc") +>cb : Symbol(cb, Decl(dependentDestructuredVariables.ts, 288, 21)) + } + } +}; + diff --git a/tests/baselines/reference/dependentDestructuredVariables.types b/tests/baselines/reference/dependentDestructuredVariables.types index a1b16d186ee08..3f0ee678974f8 100644 --- a/tests/baselines/reference/dependentDestructuredVariables.types +++ b/tests/baselines/reference/dependentDestructuredVariables.types @@ -677,3 +677,181 @@ reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] }); >3 : 3 >4 : 4 +// repro from https://github.com/microsoft/TypeScript/pull/47190#issuecomment-1057603588 + +type FooMethod = { +>FooMethod : FooMethod + + method(...args: +>method : (...args: [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void]) => void +>args : [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void] + + [type: "str", cb: (e: string) => void] | +>e : string + + [type: "num", cb: (e: number) => void] +>e : number + + ): void; +} + +let fooM: FooMethod = { +>fooM : FooMethod +>{ method(type, cb) { if (type == 'num') { cb(123) } else { cb("abc") } }} : { method(type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)): void; } + + method(type, cb) { +>method : (type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)) => void +>type : "str" | "num" +>cb : ((e: string) => void) | ((e: number) => void) + + if (type == 'num') { +>type == 'num' : boolean +>type : "str" | "num" +>'num' : "num" + + cb(123) +>cb(123) : void +>cb : (e: number) => void +>123 : 123 + + } else { + cb("abc") +>cb("abc") : void +>cb : (e: string) => void +>"abc" : "abc" + } + } +}; + +type FooAsyncMethod = { +>FooAsyncMethod : FooAsyncMethod + + method(...args: +>method : (...args: [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void]) => Promise +>args : [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void] + + [type: "str", cb: (e: string) => void] | +>e : string + + [type: "num", cb: (e: number) => void] +>e : number + + ): Promise; +} + +let fooAsyncM: FooAsyncMethod = { +>fooAsyncM : FooAsyncMethod +>{ async method(type, cb) { if (type == 'num') { cb(123) } else { cb("abc") } }} : { method(type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)): Promise; } + + async method(type, cb) { +>method : (type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)) => Promise +>type : "str" | "num" +>cb : ((e: string) => void) | ((e: number) => void) + + if (type == 'num') { +>type == 'num' : boolean +>type : "str" | "num" +>'num' : "num" + + cb(123) +>cb(123) : void +>cb : (e: number) => void +>123 : 123 + + } else { + cb("abc") +>cb("abc") : void +>cb : (e: string) => void +>"abc" : "abc" + } + } +}; + +type FooGenMethod = { +>FooGenMethod : FooGenMethod + + method(...args: +>method : (...args: [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void]) => Generator +>args : [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void] + + [type: "str", cb: (e: string) => void] | +>e : string + + [type: "num", cb: (e: number) => void] +>e : number + + ): Generator; +} + +let fooGenM: FooGenMethod = { +>fooGenM : FooGenMethod +>{ *method(type, cb) { if (type == 'num') { cb(123) } else { cb("abc") } }} : { method(type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)): Generator; } + + *method(type, cb) { +>method : (type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)) => Generator +>type : "str" | "num" +>cb : ((e: string) => void) | ((e: number) => void) + + if (type == 'num') { +>type == 'num' : boolean +>type : "str" | "num" +>'num' : "num" + + cb(123) +>cb(123) : void +>cb : (e: number) => void +>123 : 123 + + } else { + cb("abc") +>cb("abc") : void +>cb : (e: string) => void +>"abc" : "abc" + } + } +}; + +type FooAsyncGenMethod = { +>FooAsyncGenMethod : FooAsyncGenMethod + + method(...args: +>method : (...args: [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void]) => AsyncGenerator +>args : [type: "str", cb: (e: string) => void] | [type: "num", cb: (e: number) => void] + + [type: "str", cb: (e: string) => void] | +>e : string + + [type: "num", cb: (e: number) => void] +>e : number + + ): AsyncGenerator; +} + +let fooAsyncGenM: FooAsyncGenMethod = { +>fooAsyncGenM : FooAsyncGenMethod +>{ async *method(type, cb) { if (type == 'num') { cb(123) } else { cb("abc") } }} : { method(type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)): AsyncGenerator; } + + async *method(type, cb) { +>method : (type: "str" | "num", cb: ((e: string) => void) | ((e: number) => void)) => AsyncGenerator +>type : "str" | "num" +>cb : ((e: string) => void) | ((e: number) => void) + + if (type == 'num') { +>type == 'num' : boolean +>type : "str" | "num" +>'num' : "num" + + cb(123) +>cb(123) : void +>cb : (e: number) => void +>123 : 123 + + } else { + cb("abc") +>cb("abc") : void +>cb : (e: string) => void +>"abc" : "abc" + } + } +}; + diff --git a/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts b/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts index 38bcb68d048e8..2b1d64fc3bac8 100644 --- a/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts +++ b/tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts @@ -1,6 +1,7 @@ // @strict: true // @declaration: true // @target: es2015 +// @lib: esnext, dom type Action = | { kind: 'A', payload: number } @@ -228,3 +229,73 @@ const reducer: (...args: ReducerArgs) => void = (op, args) => { reducer("add", { a: 1, b: 3 }); reducer("concat", { firstArr: [1, 2], secondArr: [3, 4] }); + +// repro from https://github.com/microsoft/TypeScript/pull/47190#issuecomment-1057603588 + +type FooMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): void; +} + +let fooM: FooMethod = { + method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +}; + +type FooAsyncMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): Promise; +} + +let fooAsyncM: FooAsyncMethod = { + async method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +}; + +type FooGenMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): Generator; +} + +let fooGenM: FooGenMethod = { + *method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +}; + +type FooAsyncGenMethod = { + method(...args: + [type: "str", cb: (e: string) => void] | + [type: "num", cb: (e: number) => void] + ): AsyncGenerator; +} + +let fooAsyncGenM: FooAsyncGenMethod = { + async *method(type, cb) { + if (type == 'num') { + cb(123) + } else { + cb("abc") + } + } +};