diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2c9344679abd8..f9d139f7deeb2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36674,9 +36674,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let hasReturnWithNoExpression = functionHasImplicitReturn(func); let hasReturnOfTypeNever = false; forEachReturnStatement(func.body as Block, returnStatement => { - const expr = returnStatement.expression; + let expr = returnStatement.expression; if (expr) { + expr = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true); // Bare calls to this same function don't contribute to inference + // and `return await` is also safe to unwrap here + if (functionFlags & FunctionFlags.Async && expr.kind === SyntaxKind.AwaitExpression) { + expr = skipParentheses((expr as AwaitExpression).expression, /*excludeJSDocTypeAssertions*/ true); + } if ( expr.kind === SyntaxKind.CallExpression && (expr as CallExpression).expression.kind === SyntaxKind.Identifier && diff --git a/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.symbols b/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.symbols new file mode 100644 index 0000000000000..0bc8cf09402e8 --- /dev/null +++ b/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.symbols @@ -0,0 +1,25 @@ +//// [tests/cases/compiler/parenthesizedJSDocCastAtReturnStatement.ts] //// + +=== index.js === +/** @type {Map>} */ +const cache = new Map() +>cache : Symbol(cache, Decl(index.js, 1, 5)) +>Map : Symbol(Map, Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.collection.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) + +/** + * @param {string} key + * @returns {() => string} + */ +const getStringGetter = (key) => { +>getStringGetter : Symbol(getStringGetter, Decl(index.js, 7, 5)) +>key : Symbol(key, Decl(index.js, 7, 25)) + + return () => { + return /** @type {string} */ (cache.get(key)) +>cache.get : Symbol(Map.get, Decl(lib.es2015.collection.d.ts, --, --)) +>cache : Symbol(cache, Decl(index.js, 1, 5)) +>get : Symbol(Map.get, Decl(lib.es2015.collection.d.ts, --, --)) +>key : Symbol(key, Decl(index.js, 7, 25)) + } +} + diff --git a/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.types b/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.types new file mode 100644 index 0000000000000..cc1d5a66f92f9 --- /dev/null +++ b/tests/baselines/reference/parenthesizedJSDocCastAtReturnStatement.types @@ -0,0 +1,31 @@ +//// [tests/cases/compiler/parenthesizedJSDocCastAtReturnStatement.ts] //// + +=== index.js === +/** @type {Map>} */ +const cache = new Map() +>cache : Map> +>new Map() : Map +>Map : MapConstructor + +/** + * @param {string} key + * @returns {() => string} + */ +const getStringGetter = (key) => { +>getStringGetter : (key: string) => () => string +>(key) => { return () => { return /** @type {string} */ (cache.get(key)) }} : (key: string) => () => string +>key : string + + return () => { +>() => { return /** @type {string} */ (cache.get(key)) } : () => string + + return /** @type {string} */ (cache.get(key)) +>(cache.get(key)) : string +>cache.get(key) : string | Set | undefined +>cache.get : (key: string) => string | Set | undefined +>cache : Map> +>get : (key: string) => string | Set | undefined +>key : string + } +} + diff --git a/tests/baselines/reference/simpleRecursionWithBaseCase.symbols b/tests/baselines/reference/simpleRecursionWithBaseCase.symbols deleted file mode 100644 index ffee8b1acba5d..0000000000000 --- a/tests/baselines/reference/simpleRecursionWithBaseCase.symbols +++ /dev/null @@ -1,67 +0,0 @@ -//// [tests/cases/compiler/simpleRecursionWithBaseCase.ts] //// - -=== simpleRecursionWithBaseCase.ts === -function fn1(n: number) { ->fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase.ts, 0, 0)) ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 0, 13)) - - if (n === 0) { ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 0, 13)) - - return 3; - } else { - return fn1(n - 1); ->fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase.ts, 0, 0)) ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 0, 13)) - } -} -const num: number = fn1(); ->num : Symbol(num, Decl(simpleRecursionWithBaseCase.ts, 7, 5)) ->fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase.ts, 0, 0)) - -function fn2(n: number) { ->fn2 : Symbol(fn2, Decl(simpleRecursionWithBaseCase.ts, 7, 26)) ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 9, 13)) - - return fn2(n); ->fn2 : Symbol(fn2, Decl(simpleRecursionWithBaseCase.ts, 7, 26)) ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 9, 13)) -} -const nev: never = fn2(); ->nev : Symbol(nev, Decl(simpleRecursionWithBaseCase.ts, 12, 5)) ->fn2 : Symbol(fn2, Decl(simpleRecursionWithBaseCase.ts, 7, 26)) - -function fn3(n: number) { ->fn3 : Symbol(fn3, Decl(simpleRecursionWithBaseCase.ts, 12, 25)) ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 14, 13)) - - if (n === 0) { ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 14, 13)) - - return 3; - } else { - return fn1("hello world"); ->fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase.ts, 0, 0)) - } -} - -function fn4(n: number) { ->fn4 : Symbol(fn4, Decl(simpleRecursionWithBaseCase.ts, 20, 1)) ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 22, 13)) - - if (n === 0) { ->n : Symbol(n, Decl(simpleRecursionWithBaseCase.ts, 22, 13)) - - return 3; - } else { - return notfoundsymbol("hello world"); - } -} - -function fn5() { ->fn5 : Symbol(fn5, Decl(simpleRecursionWithBaseCase.ts, 28, 1)) - - return [fn5][0](); ->fn5 : Symbol(fn5, Decl(simpleRecursionWithBaseCase.ts, 28, 1)) -} - diff --git a/tests/baselines/reference/simpleRecursionWithBaseCase.errors.txt b/tests/baselines/reference/simpleRecursionWithBaseCase1.errors.txt similarity index 59% rename from tests/baselines/reference/simpleRecursionWithBaseCase.errors.txt rename to tests/baselines/reference/simpleRecursionWithBaseCase1.errors.txt index 5e30f2578cccb..77c1830dc6961 100644 --- a/tests/baselines/reference/simpleRecursionWithBaseCase.errors.txt +++ b/tests/baselines/reference/simpleRecursionWithBaseCase1.errors.txt @@ -1,11 +1,11 @@ -simpleRecursionWithBaseCase.ts(8,21): error TS2554: Expected 1 arguments, but got 0. -simpleRecursionWithBaseCase.ts(13,20): error TS2554: Expected 1 arguments, but got 0. -simpleRecursionWithBaseCase.ts(19,20): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. -simpleRecursionWithBaseCase.ts(27,16): error TS2304: Cannot find name 'notfoundsymbol'. -simpleRecursionWithBaseCase.ts(31,10): error TS7023: 'fn5' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. +simpleRecursionWithBaseCase1.ts(8,21): error TS2554: Expected 1 arguments, but got 0. +simpleRecursionWithBaseCase1.ts(13,20): error TS2554: Expected 1 arguments, but got 0. +simpleRecursionWithBaseCase1.ts(19,20): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +simpleRecursionWithBaseCase1.ts(27,16): error TS2304: Cannot find name 'notfoundsymbol'. +simpleRecursionWithBaseCase1.ts(31,10): error TS7023: 'fn5' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. -==== simpleRecursionWithBaseCase.ts (5 errors) ==== +==== simpleRecursionWithBaseCase1.ts (5 errors) ==== function fn1(n: number) { if (n === 0) { return 3; @@ -16,7 +16,7 @@ simpleRecursionWithBaseCase.ts(31,10): error TS7023: 'fn5' implicitly has return const num: number = fn1(); ~~~~~ !!! error TS2554: Expected 1 arguments, but got 0. -!!! related TS6210 simpleRecursionWithBaseCase.ts:1:14: An argument for 'n' was not provided. +!!! related TS6210 simpleRecursionWithBaseCase1.ts:1:14: An argument for 'n' was not provided. function fn2(n: number) { return fn2(n); @@ -24,7 +24,7 @@ simpleRecursionWithBaseCase.ts(31,10): error TS7023: 'fn5' implicitly has return const nev: never = fn2(); ~~~~~ !!! error TS2554: Expected 1 arguments, but got 0. -!!! related TS6210 simpleRecursionWithBaseCase.ts:10:14: An argument for 'n' was not provided. +!!! related TS6210 simpleRecursionWithBaseCase1.ts:10:14: An argument for 'n' was not provided. function fn3(n: number) { if (n === 0) { diff --git a/tests/baselines/reference/simpleRecursionWithBaseCase.js b/tests/baselines/reference/simpleRecursionWithBaseCase1.js similarity index 84% rename from tests/baselines/reference/simpleRecursionWithBaseCase.js rename to tests/baselines/reference/simpleRecursionWithBaseCase1.js index 41711a8089af4..d743dffeaa636 100644 --- a/tests/baselines/reference/simpleRecursionWithBaseCase.js +++ b/tests/baselines/reference/simpleRecursionWithBaseCase1.js @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/simpleRecursionWithBaseCase.ts] //// +//// [tests/cases/compiler/simpleRecursionWithBaseCase1.ts] //// -//// [simpleRecursionWithBaseCase.ts] +//// [simpleRecursionWithBaseCase1.ts] function fn1(n: number) { if (n === 0) { return 3; @@ -36,7 +36,7 @@ function fn5() { } -//// [simpleRecursionWithBaseCase.js] +//// [simpleRecursionWithBaseCase1.js] "use strict"; function fn1(n) { if (n === 0) { diff --git a/tests/baselines/reference/simpleRecursionWithBaseCase1.symbols b/tests/baselines/reference/simpleRecursionWithBaseCase1.symbols new file mode 100644 index 0000000000000..23d282c63ee0c --- /dev/null +++ b/tests/baselines/reference/simpleRecursionWithBaseCase1.symbols @@ -0,0 +1,67 @@ +//// [tests/cases/compiler/simpleRecursionWithBaseCase1.ts] //// + +=== simpleRecursionWithBaseCase1.ts === +function fn1(n: number) { +>fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase1.ts, 0, 0)) +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 0, 13)) + + if (n === 0) { +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 0, 13)) + + return 3; + } else { + return fn1(n - 1); +>fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase1.ts, 0, 0)) +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 0, 13)) + } +} +const num: number = fn1(); +>num : Symbol(num, Decl(simpleRecursionWithBaseCase1.ts, 7, 5)) +>fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase1.ts, 0, 0)) + +function fn2(n: number) { +>fn2 : Symbol(fn2, Decl(simpleRecursionWithBaseCase1.ts, 7, 26)) +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 9, 13)) + + return fn2(n); +>fn2 : Symbol(fn2, Decl(simpleRecursionWithBaseCase1.ts, 7, 26)) +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 9, 13)) +} +const nev: never = fn2(); +>nev : Symbol(nev, Decl(simpleRecursionWithBaseCase1.ts, 12, 5)) +>fn2 : Symbol(fn2, Decl(simpleRecursionWithBaseCase1.ts, 7, 26)) + +function fn3(n: number) { +>fn3 : Symbol(fn3, Decl(simpleRecursionWithBaseCase1.ts, 12, 25)) +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 14, 13)) + + if (n === 0) { +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 14, 13)) + + return 3; + } else { + return fn1("hello world"); +>fn1 : Symbol(fn1, Decl(simpleRecursionWithBaseCase1.ts, 0, 0)) + } +} + +function fn4(n: number) { +>fn4 : Symbol(fn4, Decl(simpleRecursionWithBaseCase1.ts, 20, 1)) +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 22, 13)) + + if (n === 0) { +>n : Symbol(n, Decl(simpleRecursionWithBaseCase1.ts, 22, 13)) + + return 3; + } else { + return notfoundsymbol("hello world"); + } +} + +function fn5() { +>fn5 : Symbol(fn5, Decl(simpleRecursionWithBaseCase1.ts, 28, 1)) + + return [fn5][0](); +>fn5 : Symbol(fn5, Decl(simpleRecursionWithBaseCase1.ts, 28, 1)) +} + diff --git a/tests/baselines/reference/simpleRecursionWithBaseCase.types b/tests/baselines/reference/simpleRecursionWithBaseCase1.types similarity index 87% rename from tests/baselines/reference/simpleRecursionWithBaseCase.types rename to tests/baselines/reference/simpleRecursionWithBaseCase1.types index e80cb0852389a..e05a9c8542267 100644 --- a/tests/baselines/reference/simpleRecursionWithBaseCase.types +++ b/tests/baselines/reference/simpleRecursionWithBaseCase1.types @@ -1,6 +1,6 @@ -//// [tests/cases/compiler/simpleRecursionWithBaseCase.ts] //// +//// [tests/cases/compiler/simpleRecursionWithBaseCase1.ts] //// -=== simpleRecursionWithBaseCase.ts === +=== simpleRecursionWithBaseCase1.ts === function fn1(n: number) { >fn1 : (n: number) => number >n : number diff --git a/tests/baselines/reference/simpleRecursionWithBaseCase2.symbols b/tests/baselines/reference/simpleRecursionWithBaseCase2.symbols new file mode 100644 index 0000000000000..5d1360373648a --- /dev/null +++ b/tests/baselines/reference/simpleRecursionWithBaseCase2.symbols @@ -0,0 +1,119 @@ +//// [tests/cases/compiler/simpleRecursionWithBaseCase2.ts] //// + +=== simpleRecursionWithBaseCase2.ts === +async function rec1() { +>rec1 : Symbol(rec1, Decl(simpleRecursionWithBaseCase2.ts, 0, 0)) + + if (Math.random() < 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return rec1(); +>rec1 : Symbol(rec1, Decl(simpleRecursionWithBaseCase2.ts, 0, 0)) + + } else { + return "hello"; + } +} + +async function rec2() { +>rec2 : Symbol(rec2, Decl(simpleRecursionWithBaseCase2.ts, 6, 1)) + + if (Math.random() < 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return await rec2(); +>rec2 : Symbol(rec2, Decl(simpleRecursionWithBaseCase2.ts, 6, 1)) + + } else { + return "hello"; + } +} + +async function rec3() { +>rec3 : Symbol(rec3, Decl(simpleRecursionWithBaseCase2.ts, 14, 1)) + + return rec3(); +>rec3 : Symbol(rec3, Decl(simpleRecursionWithBaseCase2.ts, 14, 1)) +} + +async function rec4() { +>rec4 : Symbol(rec4, Decl(simpleRecursionWithBaseCase2.ts, 18, 1)) + + return await rec4(); +>rec4 : Symbol(rec4, Decl(simpleRecursionWithBaseCase2.ts, 18, 1)) +} + +async function rec5() { +>rec5 : Symbol(rec5, Decl(simpleRecursionWithBaseCase2.ts, 22, 1)) + + if (Math.random() < 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return ((rec1())); +>rec1 : Symbol(rec1, Decl(simpleRecursionWithBaseCase2.ts, 0, 0)) + + } else { + return "hello"; + } +} + +async function rec6() { +>rec6 : Symbol(rec6, Decl(simpleRecursionWithBaseCase2.ts, 30, 1)) + + if (Math.random() < 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return await ((rec1())); +>rec1 : Symbol(rec1, Decl(simpleRecursionWithBaseCase2.ts, 0, 0)) + + } else { + return "hello"; + } +} + +declare const ps: Promise | number; +>ps : Symbol(ps, Decl(simpleRecursionWithBaseCase2.ts, 40, 13)) +>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, --, --)) + +async function foo1() { +>foo1 : Symbol(foo1, Decl(simpleRecursionWithBaseCase2.ts, 40, 43)) + + if (Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return ps; +>ps : Symbol(ps, Decl(simpleRecursionWithBaseCase2.ts, 40, 13)) + + } else { + return await foo1(); +>foo1 : Symbol(foo1, Decl(simpleRecursionWithBaseCase2.ts, 40, 43)) + } +} + +async function foo2() { +>foo2 : Symbol(foo2, Decl(simpleRecursionWithBaseCase2.ts, 48, 1)) + + if (Math.random() > 0.5) { +>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --)) +>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) + + return ps; +>ps : Symbol(ps, Decl(simpleRecursionWithBaseCase2.ts, 40, 13)) + + } else { + return foo2(); +>foo2 : Symbol(foo2, Decl(simpleRecursionWithBaseCase2.ts, 48, 1)) + } +} + diff --git a/tests/baselines/reference/simpleRecursionWithBaseCase2.types b/tests/baselines/reference/simpleRecursionWithBaseCase2.types new file mode 100644 index 0000000000000..2afe3c81fe794 --- /dev/null +++ b/tests/baselines/reference/simpleRecursionWithBaseCase2.types @@ -0,0 +1,156 @@ +//// [tests/cases/compiler/simpleRecursionWithBaseCase2.ts] //// + +=== simpleRecursionWithBaseCase2.ts === +async function rec1() { +>rec1 : () => Promise + + if (Math.random() < 0.5) { +>Math.random() < 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return rec1(); +>rec1() : Promise +>rec1 : () => Promise + + } else { + return "hello"; +>"hello" : "hello" + } +} + +async function rec2() { +>rec2 : () => Promise + + if (Math.random() < 0.5) { +>Math.random() < 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return await rec2(); +>await rec2() : string +>rec2() : Promise +>rec2 : () => Promise + + } else { + return "hello"; +>"hello" : "hello" + } +} + +async function rec3() { +>rec3 : () => Promise + + return rec3(); +>rec3() : Promise +>rec3 : () => Promise +} + +async function rec4() { +>rec4 : () => Promise + + return await rec4(); +>await rec4() : never +>rec4() : Promise +>rec4 : () => Promise +} + +async function rec5() { +>rec5 : () => Promise + + if (Math.random() < 0.5) { +>Math.random() < 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return ((rec1())); +>((rec1())) : Promise +>(rec1()) : Promise +>rec1() : Promise +>rec1 : () => Promise + + } else { + return "hello"; +>"hello" : "hello" + } +} + +async function rec6() { +>rec6 : () => Promise + + if (Math.random() < 0.5) { +>Math.random() < 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return await ((rec1())); +>await ((rec1())) : string +>((rec1())) : Promise +>(rec1()) : Promise +>rec1() : Promise +>rec1 : () => Promise + + } else { + return "hello"; +>"hello" : "hello" + } +} + +declare const ps: Promise | number; +>ps : number | Promise + +async function foo1() { +>foo1 : () => Promise + + if (Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return ps; +>ps : number | Promise + + } else { + return await foo1(); +>await foo1() : string | number +>foo1() : Promise +>foo1 : () => Promise + } +} + +async function foo2() { +>foo2 : () => Promise + + if (Math.random() > 0.5) { +>Math.random() > 0.5 : boolean +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number +>0.5 : 0.5 + + return ps; +>ps : number | Promise + + } else { + return foo2(); +>foo2() : Promise +>foo2 : () => Promise + } +} + diff --git a/tests/cases/compiler/parenthesizedJSDocCastAtReturnStatement.ts b/tests/cases/compiler/parenthesizedJSDocCastAtReturnStatement.ts new file mode 100644 index 0000000000000..d6cdd49f42f9c --- /dev/null +++ b/tests/cases/compiler/parenthesizedJSDocCastAtReturnStatement.ts @@ -0,0 +1,20 @@ +// @strict: true +// @lib: esnext +// @noEmit: true +// @checkJs: true +// @allowJs: true + +// @filename: index.js + +/** @type {Map>} */ +const cache = new Map() + +/** + * @param {string} key + * @returns {() => string} + */ +const getStringGetter = (key) => { + return () => { + return /** @type {string} */ (cache.get(key)) + } +} diff --git a/tests/cases/compiler/simpleRecursionWithBaseCase.ts b/tests/cases/compiler/simpleRecursionWithBaseCase1.ts similarity index 100% rename from tests/cases/compiler/simpleRecursionWithBaseCase.ts rename to tests/cases/compiler/simpleRecursionWithBaseCase1.ts diff --git a/tests/cases/compiler/simpleRecursionWithBaseCase2.ts b/tests/cases/compiler/simpleRecursionWithBaseCase2.ts new file mode 100644 index 0000000000000..b5ab3ac417d18 --- /dev/null +++ b/tests/cases/compiler/simpleRecursionWithBaseCase2.ts @@ -0,0 +1,62 @@ +// @strict: true +// @noImplicitAny: true +// @lib: esnext +// @noEmit: true + +async function rec1() { + if (Math.random() < 0.5) { + return rec1(); + } else { + return "hello"; + } +} + +async function rec2() { + if (Math.random() < 0.5) { + return await rec2(); + } else { + return "hello"; + } +} + +async function rec3() { + return rec3(); +} + +async function rec4() { + return await rec4(); +} + +async function rec5() { + if (Math.random() < 0.5) { + return ((rec1())); + } else { + return "hello"; + } +} + +async function rec6() { + if (Math.random() < 0.5) { + return await ((rec1())); + } else { + return "hello"; + } +} + +declare const ps: Promise | number; + +async function foo1() { + if (Math.random() > 0.5) { + return ps; + } else { + return await foo1(); + } +} + +async function foo2() { + if (Math.random() > 0.5) { + return ps; + } else { + return foo2(); + } +}