From 6ad94f1d756ca5691fe8a6369ebba77ea9a83a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 23 Dec 2023 14:50:46 +0100 Subject: [PATCH 1/4] Keep returned (and yielded) literal types as const when their types using `const` type variables --- src/compiler/checker.ts | 7 +- ...eterConstModifiersReturnsAndYields.symbols | 153 +++++++++++++ ...ameterConstModifiersReturnsAndYields.types | 208 ++++++++++++++++++ ...ParameterConstModifiersReturnsAndYields.ts | 47 ++++ 4 files changed, 413 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols create mode 100644 tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types create mode 100644 tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3d4f288f1293b..a87fae88ce939 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36825,6 +36825,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let fallbackReturnType: Type = voidType; if (func.body.kind !== SyntaxKind.Block) { // Async or normal arrow function returnType = checkExpressionCached(func.body, checkMode && checkMode & ~CheckMode.SkipGenericFunctions); + if (isConstContext(func.body)) { + returnType = getRegularTypeOfLiteralType(returnType); + } if (isAsync) { // From within an async function you can return either a non-promise value or a promise. Any // Promise/A+ compatible implementation will always assimilate any foreign promise, so the @@ -36952,7 +36955,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const isAsync = (getFunctionFlags(func) & FunctionFlags.Async) !== 0; forEachYieldExpression(func.body as Block, yieldExpression => { const yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType; - pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpressionType, anyType, isAsync)); + pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpression.expression && isConstContext(yieldExpression.expression) ? getRegularTypeOfLiteralType(yieldExpressionType) : yieldExpressionType, anyType, isAsync)); let nextType: Type | undefined; if (yieldExpression.asteriskToken) { const iterationTypes = getIterationTypesOfIterable( @@ -37074,7 +37077,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (type.flags & TypeFlags.Never) { hasReturnOfTypeNever = true; } - pushIfUnique(aggregatedTypes, type); + pushIfUnique(aggregatedTypes, isConstContext(expr) ? getRegularTypeOfLiteralType(type) : type); } else { hasReturnWithNoExpression = true; diff --git a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols new file mode 100644 index 0000000000000..678e4f1c347dd --- /dev/null +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols @@ -0,0 +1,153 @@ +//// [tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts] //// + +=== typeParameterConstModifiersReturnsAndYields.ts === +enum E { Val, Val2 } +>E : Symbol(E, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 0)) +>Val : Symbol(E.Val, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 8)) +>Val2 : Symbol(E.Val2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 13)) + +declare function test1(create: () => T): T; +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 2, 23)) +>create : Symbol(create, Decl(typeParameterConstModifiersReturnsAndYields.ts, 2, 32)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 2, 23)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 2, 23)) + +const result1 = test1(() => ['a']); +>result1 : Symbol(result1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 4, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result2 = test1(() => `a${Math.random()}`); +>result2 : Symbol(result2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 5, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) +>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, --, --)) + +const result3 = test1(() => 'a'); +>result3 : Symbol(result3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 6, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result4 = test1(() => true); +>result4 : Symbol(result4, Decl(typeParameterConstModifiersReturnsAndYields.ts, 7, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result5 = test1(() => 101n); +>result5 : Symbol(result5, Decl(typeParameterConstModifiersReturnsAndYields.ts, 8, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result6 = test1(() => false); +>result6 : Symbol(result6, Decl(typeParameterConstModifiersReturnsAndYields.ts, 9, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result7 = test1(() => 11111); +>result7 : Symbol(result7, Decl(typeParameterConstModifiersReturnsAndYields.ts, 10, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result8 = test1(() => E.Val); +>result8 : Symbol(result8, Decl(typeParameterConstModifiersReturnsAndYields.ts, 11, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) +>E.Val : Symbol(E.Val, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 8)) +>E : Symbol(E, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 0)) +>Val : Symbol(E.Val, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 8)) + +const result9 = test1(() => { return ['a']; }); +>result9 : Symbol(result9, Decl(typeParameterConstModifiersReturnsAndYields.ts, 13, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result10 = test1(() => { return `a${Math.random()}`; }); +>result10 : Symbol(result10, Decl(typeParameterConstModifiersReturnsAndYields.ts, 14, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) +>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, --, --)) + +const result11 = test1(() => { return 'a'; }); +>result11 : Symbol(result11, Decl(typeParameterConstModifiersReturnsAndYields.ts, 15, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result12 = test1(() => { return true; }); +>result12 : Symbol(result12, Decl(typeParameterConstModifiersReturnsAndYields.ts, 16, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result13 = test1(() => { return 101n; }); +>result13 : Symbol(result13, Decl(typeParameterConstModifiersReturnsAndYields.ts, 17, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result14 = test1(() => { return false; }); +>result14 : Symbol(result14, Decl(typeParameterConstModifiersReturnsAndYields.ts, 18, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result15 = test1(() => { return 11111; }); +>result15 : Symbol(result15, Decl(typeParameterConstModifiersReturnsAndYields.ts, 19, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result16 = test1(() => { return E.Val; }); +>result16 : Symbol(result16, Decl(typeParameterConstModifiersReturnsAndYields.ts, 20, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) +>E.Val : Symbol(E.Val, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 8)) +>E : Symbol(E, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 0)) +>Val : Symbol(E.Val, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 8)) + +const result17 = test1(async () => 'foo'); +>result17 : Symbol(result17, Decl(typeParameterConstModifiersReturnsAndYields.ts, 22, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +const result18 = test1(async () => { return 'foo'; }); +>result18 : Symbol(result18, Decl(typeParameterConstModifiersReturnsAndYields.ts, 23, 5)) +>test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) + +declare function test2(create: () => Promise): T; +>test2 : Symbol(test2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 23, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 25, 23)) +>create : Symbol(create, Decl(typeParameterConstModifiersReturnsAndYields.ts, 25, 32)) +>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, --, --)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 25, 23)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 25, 23)) + +const result19 = test2(async () => 'foo'); +>result19 : Symbol(result19, Decl(typeParameterConstModifiersReturnsAndYields.ts, 27, 5)) +>test2 : Symbol(test2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 23, 54)) + +const result20 = test2(async () => { return 'foo'; }); +>result20 : Symbol(result20, Decl(typeParameterConstModifiersReturnsAndYields.ts, 28, 5)) +>test2 : Symbol(test2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 23, 54)) + +declare function test3(arg: () => Generator): [T, R] +>test3 : Symbol(test3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 28, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 30, 23)) +>R : Symbol(R, Decl(typeParameterConstModifiersReturnsAndYields.ts, 30, 31)) +>arg : Symbol(arg, Decl(typeParameterConstModifiersReturnsAndYields.ts, 30, 41)) +>Generator : Symbol(Generator, Decl(lib.es2015.generator.d.ts, --, --)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 30, 23)) +>R : Symbol(R, Decl(typeParameterConstModifiersReturnsAndYields.ts, 30, 31)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 30, 23)) +>R : Symbol(R, Decl(typeParameterConstModifiersReturnsAndYields.ts, 30, 31)) + +const result21 = test3(function*() { +>result21 : Symbol(result21, Decl(typeParameterConstModifiersReturnsAndYields.ts, 32, 5)) +>test3 : Symbol(test3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 28, 54)) + + yield 10; + return '1'; +}); + +declare function test4(arg: () => AsyncGenerator): [T, R] +>test4 : Symbol(test4, Decl(typeParameterConstModifiersReturnsAndYields.ts, 35, 3)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 37, 23)) +>R : Symbol(R, Decl(typeParameterConstModifiersReturnsAndYields.ts, 37, 31)) +>arg : Symbol(arg, Decl(typeParameterConstModifiersReturnsAndYields.ts, 37, 41)) +>AsyncGenerator : Symbol(AsyncGenerator, Decl(lib.es2018.asyncgenerator.d.ts, --, --)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 37, 23)) +>R : Symbol(R, Decl(typeParameterConstModifiersReturnsAndYields.ts, 37, 31)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 37, 23)) +>R : Symbol(R, Decl(typeParameterConstModifiersReturnsAndYields.ts, 37, 31)) + +const result22 = test4(async function*() { +>result22 : Symbol(result22, Decl(typeParameterConstModifiersReturnsAndYields.ts, 39, 5)) +>test4 : Symbol(test4, Decl(typeParameterConstModifiersReturnsAndYields.ts, 35, 3)) + + yield 10; + return '1'; +}); + diff --git a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types new file mode 100644 index 0000000000000..2eabbbedd9268 --- /dev/null +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types @@ -0,0 +1,208 @@ +//// [tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts] //// + +=== typeParameterConstModifiersReturnsAndYields.ts === +enum E { Val, Val2 } +>E : E +>Val : E.Val +>Val2 : E.Val2 + +declare function test1(create: () => T): T; +>test1 : (create: () => T) => T +>create : () => T + +const result1 = test1(() => ['a']); +>result1 : readonly ["a"] +>test1(() => ['a']) : readonly ["a"] +>test1 : (create: () => T) => T +>() => ['a'] : () => readonly ["a"] +>['a'] : ["a"] +>'a' : "a" + +const result2 = test1(() => `a${Math.random()}`); +>result2 : `a${number}` +>test1(() => `a${Math.random()}`) : `a${number}` +>test1 : (create: () => T) => T +>() => `a${Math.random()}` : () => `a${number}` +>`a${Math.random()}` : `a${number}` +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number + +const result3 = test1(() => 'a'); +>result3 : "a" +>test1(() => 'a') : "a" +>test1 : (create: () => T) => T +>() => 'a' : () => "a" +>'a' : "a" + +const result4 = test1(() => true); +>result4 : true +>test1(() => true) : true +>test1 : (create: () => T) => T +>() => true : () => true +>true : true + +const result5 = test1(() => 101n); +>result5 : 101n +>test1(() => 101n) : 101n +>test1 : (create: () => T) => T +>() => 101n : () => 101n +>101n : 101n + +const result6 = test1(() => false); +>result6 : false +>test1(() => false) : false +>test1 : (create: () => T) => T +>() => false : () => false +>false : false + +const result7 = test1(() => 11111); +>result7 : 11111 +>test1(() => 11111) : 11111 +>test1 : (create: () => T) => T +>() => 11111 : () => 11111 +>11111 : 11111 + +const result8 = test1(() => E.Val); +>result8 : E.Val +>test1(() => E.Val) : E.Val +>test1 : (create: () => T) => T +>() => E.Val : () => E.Val +>E.Val : E.Val +>E : typeof E +>Val : E.Val + +const result9 = test1(() => { return ['a']; }); +>result9 : readonly ["a"] +>test1(() => { return ['a']; }) : readonly ["a"] +>test1 : (create: () => T) => T +>() => { return ['a']; } : () => readonly ["a"] +>['a'] : ["a"] +>'a' : "a" + +const result10 = test1(() => { return `a${Math.random()}`; }); +>result10 : `a${number}` +>test1(() => { return `a${Math.random()}`; }) : `a${number}` +>test1 : (create: () => T) => T +>() => { return `a${Math.random()}`; } : () => `a${number}` +>`a${Math.random()}` : `a${number}` +>Math.random() : number +>Math.random : () => number +>Math : Math +>random : () => number + +const result11 = test1(() => { return 'a'; }); +>result11 : "a" +>test1(() => { return 'a'; }) : "a" +>test1 : (create: () => T) => T +>() => { return 'a'; } : () => "a" +>'a' : "a" + +const result12 = test1(() => { return true; }); +>result12 : true +>test1(() => { return true; }) : true +>test1 : (create: () => T) => T +>() => { return true; } : () => true +>true : true + +const result13 = test1(() => { return 101n; }); +>result13 : 101n +>test1(() => { return 101n; }) : 101n +>test1 : (create: () => T) => T +>() => { return 101n; } : () => 101n +>101n : 101n + +const result14 = test1(() => { return false; }); +>result14 : false +>test1(() => { return false; }) : false +>test1 : (create: () => T) => T +>() => { return false; } : () => false +>false : false + +const result15 = test1(() => { return 11111; }); +>result15 : 11111 +>test1(() => { return 11111; }) : 11111 +>test1 : (create: () => T) => T +>() => { return 11111; } : () => 11111 +>11111 : 11111 + +const result16 = test1(() => { return E.Val; }); +>result16 : E.Val +>test1(() => { return E.Val; }) : E.Val +>test1 : (create: () => T) => T +>() => { return E.Val; } : () => E.Val +>E.Val : E.Val +>E : typeof E +>Val : E.Val + +const result17 = test1(async () => 'foo'); +>result17 : Promise<"foo"> +>test1(async () => 'foo') : Promise<"foo"> +>test1 : (create: () => T) => T +>async () => 'foo' : () => Promise<"foo"> +>'foo' : "foo" + +const result18 = test1(async () => { return 'foo'; }); +>result18 : Promise<"foo"> +>test1(async () => { return 'foo'; }) : Promise<"foo"> +>test1 : (create: () => T) => T +>async () => { return 'foo'; } : () => Promise<"foo"> +>'foo' : "foo" + +declare function test2(create: () => Promise): T; +>test2 : (create: () => Promise) => T +>create : () => Promise + +const result19 = test2(async () => 'foo'); +>result19 : "foo" +>test2(async () => 'foo') : "foo" +>test2 : (create: () => Promise) => T +>async () => 'foo' : () => Promise<"foo"> +>'foo' : "foo" + +const result20 = test2(async () => { return 'foo'; }); +>result20 : "foo" +>test2(async () => { return 'foo'; }) : "foo" +>test2 : (create: () => Promise) => T +>async () => { return 'foo'; } : () => Promise<"foo"> +>'foo' : "foo" + +declare function test3(arg: () => Generator): [T, R] +>test3 : (arg: () => Generator) => [T, R] +>arg : () => Generator + +const result21 = test3(function*() { +>result21 : [10, "1"] +>test3(function*() { yield 10; return '1';}) : [10, "1"] +>test3 : (arg: () => Generator) => [T, R] +>function*() { yield 10; return '1';} : () => Generator<10, "1", unknown> + + yield 10; +>yield 10 : unknown +>10 : 10 + + return '1'; +>'1' : "1" + +}); + +declare function test4(arg: () => AsyncGenerator): [T, R] +>test4 : (arg: () => AsyncGenerator) => [T, R] +>arg : () => AsyncGenerator + +const result22 = test4(async function*() { +>result22 : [10, "1"] +>test4(async function*() { yield 10; return '1';}) : [10, "1"] +>test4 : (arg: () => AsyncGenerator) => [T, R] +>async function*() { yield 10; return '1';} : () => AsyncGenerator<10, "1", unknown> + + yield 10; +>yield 10 : unknown +>10 : 10 + + return '1'; +>'1' : "1" + +}); + diff --git a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts new file mode 100644 index 0000000000000..3c324616e5bf2 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts @@ -0,0 +1,47 @@ +// @strict: true +// @target: esnext +// @noEmit: true + +enum E { Val, Val2 } + +declare function test1(create: () => T): T; + +const result1 = test1(() => ['a']); +const result2 = test1(() => `a${Math.random()}`); +const result3 = test1(() => 'a'); +const result4 = test1(() => true); +const result5 = test1(() => 101n); +const result6 = test1(() => false); +const result7 = test1(() => 11111); +const result8 = test1(() => E.Val); + +const result9 = test1(() => { return ['a']; }); +const result10 = test1(() => { return `a${Math.random()}`; }); +const result11 = test1(() => { return 'a'; }); +const result12 = test1(() => { return true; }); +const result13 = test1(() => { return 101n; }); +const result14 = test1(() => { return false; }); +const result15 = test1(() => { return 11111; }); +const result16 = test1(() => { return E.Val; }); + +const result17 = test1(async () => 'foo'); +const result18 = test1(async () => { return 'foo'; }); + +declare function test2(create: () => Promise): T; + +const result19 = test2(async () => 'foo'); +const result20 = test2(async () => { return 'foo'; }); + +declare function test3(arg: () => Generator): [T, R] + +const result21 = test3(function*() { + yield 10; + return '1'; +}); + +declare function test4(arg: () => AsyncGenerator): [T, R] + +const result22 = test4(async function*() { + yield 10; + return '1'; +}); From f057c90a11f06be8bc00831ee1e1049c24d89fa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 24 Dec 2023 15:10:00 +0100 Subject: [PATCH 2/4] add an extra test case with reverse mapped types --- ...eterConstModifiersReturnsAndYields.symbols | 49 +++++++++++++++++++ ...ameterConstModifiersReturnsAndYields.types | 48 ++++++++++++++++++ ...ParameterConstModifiersReturnsAndYields.ts | 17 +++++++ 3 files changed, 114 insertions(+) diff --git a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols index 678e4f1c347dd..9127ede3b0723 100644 --- a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols @@ -151,3 +151,52 @@ const result22 = test4(async function*() { return '1'; }); +// https://github.com/microsoft/TypeScript/issues/53813 +const UploadThingServerHelper = (route: { +>UploadThingServerHelper : Symbol(UploadThingServerHelper, Decl(typeParameterConstModifiersReturnsAndYields.ts, 45, 5)) +>ValidRoutes : Symbol(ValidRoutes, Decl(typeParameterConstModifiersReturnsAndYields.ts, 45, 33)) +>route : Symbol(route, Decl(typeParameterConstModifiersReturnsAndYields.ts, 45, 53)) + + readonly [Route in keyof ValidRoutes]: { +>Route : Symbol(Route, Decl(typeParameterConstModifiersReturnsAndYields.ts, 46, 12)) +>ValidRoutes : Symbol(ValidRoutes, Decl(typeParameterConstModifiersReturnsAndYields.ts, 45, 33)) + + middleware: () => ValidRoutes[Route]; +>middleware : Symbol(middleware, Decl(typeParameterConstModifiersReturnsAndYields.ts, 46, 42)) +>ValidRoutes : Symbol(ValidRoutes, Decl(typeParameterConstModifiersReturnsAndYields.ts, 45, 33)) +>Route : Symbol(Route, Decl(typeParameterConstModifiersReturnsAndYields.ts, 46, 12)) + + onUpload: (response: { metadata: ValidRoutes[Route] }) => void; +>onUpload : Symbol(onUpload, Decl(typeParameterConstModifiersReturnsAndYields.ts, 47, 41)) +>response : Symbol(response, Decl(typeParameterConstModifiersReturnsAndYields.ts, 48, 15)) +>metadata : Symbol(metadata, Decl(typeParameterConstModifiersReturnsAndYields.ts, 48, 26)) +>ValidRoutes : Symbol(ValidRoutes, Decl(typeParameterConstModifiersReturnsAndYields.ts, 45, 33)) +>Route : Symbol(Route, Decl(typeParameterConstModifiersReturnsAndYields.ts, 46, 12)) + + }; +}) => {}; + +const FileRouter = UploadThingServerHelper({ +>FileRouter : Symbol(FileRouter, Decl(typeParameterConstModifiersReturnsAndYields.ts, 52, 5)) +>UploadThingServerHelper : Symbol(UploadThingServerHelper, Decl(typeParameterConstModifiersReturnsAndYields.ts, 45, 5)) + + example: { +>example : Symbol(example, Decl(typeParameterConstModifiersReturnsAndYields.ts, 52, 44)) + + middleware: () => "someValue", +>middleware : Symbol(middleware, Decl(typeParameterConstModifiersReturnsAndYields.ts, 53, 12)) + + onUpload: (response) => { +>onUpload : Symbol(onUpload, Decl(typeParameterConstModifiersReturnsAndYields.ts, 54, 34)) +>response : Symbol(response, Decl(typeParameterConstModifiersReturnsAndYields.ts, 55, 15)) + + const v: "someValue" = response.metadata; +>v : Symbol(v, Decl(typeParameterConstModifiersReturnsAndYields.ts, 56, 11)) +>response.metadata : Symbol(metadata, Decl(typeParameterConstModifiersReturnsAndYields.ts, 48, 26)) +>response : Symbol(response, Decl(typeParameterConstModifiersReturnsAndYields.ts, 55, 15)) +>metadata : Symbol(metadata, Decl(typeParameterConstModifiersReturnsAndYields.ts, 48, 26)) + + }, + }, +}); + diff --git a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types index 2eabbbedd9268..c0a1dfcf503b7 100644 --- a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types @@ -206,3 +206,51 @@ const result22 = test4(async function*() { }); +// https://github.com/microsoft/TypeScript/issues/53813 +const UploadThingServerHelper = (route: { +>UploadThingServerHelper : (route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; }) => void +>(route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route] }) => void; };}) => {} : (route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; }) => void +>route : { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; } + + readonly [Route in keyof ValidRoutes]: { + middleware: () => ValidRoutes[Route]; +>middleware : () => ValidRoutes[Route] + + onUpload: (response: { metadata: ValidRoutes[Route] }) => void; +>onUpload : (response: { metadata: ValidRoutes[Route];}) => void +>response : { metadata: ValidRoutes[Route]; } +>metadata : ValidRoutes[Route] + + }; +}) => {}; + +const FileRouter = UploadThingServerHelper({ +>FileRouter : void +>UploadThingServerHelper({ example: { middleware: () => "someValue", onUpload: (response) => { const v: "someValue" = response.metadata; }, },}) : void +>UploadThingServerHelper : (route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; }) => void +>{ example: { middleware: () => "someValue", onUpload: (response) => { const v: "someValue" = response.metadata; }, },} : { example: { middleware: () => "someValue"; onUpload: (response: { metadata: "someValue"; }) => void; }; } + + example: { +>example : { middleware: () => "someValue"; onUpload: (response: { metadata: "someValue"; }) => void; } +>{ middleware: () => "someValue", onUpload: (response) => { const v: "someValue" = response.metadata; }, } : { middleware: () => "someValue"; onUpload: (response: { metadata: "someValue"; }) => void; } + + middleware: () => "someValue", +>middleware : () => "someValue" +>() => "someValue" : () => "someValue" +>"someValue" : "someValue" + + onUpload: (response) => { +>onUpload : (response: { metadata: "someValue"; }) => void +>(response) => { const v: "someValue" = response.metadata; } : (response: { metadata: "someValue"; }) => void +>response : { metadata: "someValue"; } + + const v: "someValue" = response.metadata; +>v : "someValue" +>response.metadata : "someValue" +>response : { metadata: "someValue"; } +>metadata : "someValue" + + }, + }, +}); + diff --git a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts index 3c324616e5bf2..ed2f6ccaccde8 100644 --- a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts @@ -45,3 +45,20 @@ const result22 = test4(async function*() { yield 10; return '1'; }); + +// https://github.com/microsoft/TypeScript/issues/53813 +const UploadThingServerHelper = (route: { + readonly [Route in keyof ValidRoutes]: { + middleware: () => ValidRoutes[Route]; + onUpload: (response: { metadata: ValidRoutes[Route] }) => void; + }; +}) => {}; + +const FileRouter = UploadThingServerHelper({ + example: { + middleware: () => "someValue", + onUpload: (response) => { + const v: "someValue" = response.metadata; + }, + }, +}); From 78831c2d99cb516e75be263883801eb1cd1eb948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 3 Jan 2024 18:28:59 +0100 Subject: [PATCH 3/4] address review feedback --- src/compiler/checker.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9aacc83089728..6eead24f09192 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36980,8 +36980,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const nextTypes: Type[] = []; const isAsync = (getFunctionFlags(func) & FunctionFlags.Async) !== 0; forEachYieldExpression(func.body as Block, yieldExpression => { - const yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType; - pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpression.expression && isConstContext(yieldExpression.expression) ? getRegularTypeOfLiteralType(yieldExpressionType) : yieldExpressionType, anyType, isAsync)); + let yieldExpressionType = yieldExpression.expression ? checkExpression(yieldExpression.expression, checkMode) : undefinedWideningType; + if (yieldExpression.expression && isConstContext(yieldExpression.expression)) { + yieldExpressionType = getRegularTypeOfLiteralType(yieldExpressionType); + } + pushIfUnique(yieldTypes, getYieldedTypeOfYieldExpression(yieldExpression, yieldExpressionType, anyType, isAsync)); let nextType: Type | undefined; if (yieldExpression.asteriskToken) { const iterationTypes = getIterationTypesOfIterable( From 913d009483646d4d45ff7f83a5d462e24d6e4e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 10 Aug 2025 00:29:17 +0200 Subject: [PATCH 4/4] add test --- ...eterConstModifiersReturnsAndYields.symbols | 203 ++++++- ...ameterConstModifiersReturnsAndYields.types | 526 +++++++++++++++++- ...ParameterConstModifiersReturnsAndYields.ts | 49 ++ 3 files changed, 769 insertions(+), 9 deletions(-) diff --git a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols index 9127ede3b0723..9b832e9e022e4 100644 --- a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols @@ -21,7 +21,7 @@ const result2 = test1(() => `a${Math.random()}`); >result2 : Symbol(result2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 5, 5)) >test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) >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, --, --)) +>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, --, --), Decl(lib.esnext.float16.d.ts, --, --)) >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) const result3 = test1(() => 'a'); @@ -59,7 +59,7 @@ const result10 = test1(() => { return `a${Math.random()}`; }); >result10 : Symbol(result10, Decl(typeParameterConstModifiersReturnsAndYields.ts, 14, 5)) >test1 : Symbol(test1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 0, 20)) >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, --, --)) +>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, --, --), Decl(lib.esnext.float16.d.ts, --, --)) >random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --)) const result11 = test1(() => { return 'a'; }); @@ -200,3 +200,202 @@ const FileRouter = UploadThingServerHelper({ }, }); +function outer1(cb: () => T) { +>outer1 : Symbol(outer1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 59, 3)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 61, 16)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 61, 25)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 61, 16)) + + function inner1(cb2: () => U) { +>inner1 : Symbol(inner1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 61, 39)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 62, 18)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 62, 27)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 62, 18)) + + return [cb(), cb2()]; +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 61, 25)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 62, 27)) + } + return inner1; +>inner1 : Symbol(inner1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 61, 39)) +} +const nestedResult1 = outer1(() => 1)(() => "foo"); +>nestedResult1 : Symbol(nestedResult1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 67, 5)) +>outer1 : Symbol(outer1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 59, 3)) + +function outer2(cb: () => T) { +>outer2 : Symbol(outer2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 67, 51)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 69, 16)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 69, 19)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 69, 16)) + + function inner2(cb2: () => U) { +>inner2 : Symbol(inner2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 69, 33)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 70, 18)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 70, 27)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 70, 18)) + + return [cb(), cb2()]; +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 69, 19)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 70, 27)) + } + return inner2; +>inner2 : Symbol(inner2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 69, 33)) +} +const nestedResult2 = outer2(() => 1)(() => "foo"); +>nestedResult2 : Symbol(nestedResult2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 75, 5)) +>outer2 : Symbol(outer2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 67, 51)) + +function outer3(cb: () => T) { +>outer3 : Symbol(outer3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 75, 51)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 77, 16)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 77, 25)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 77, 16)) + + function inner3(cb2: () => U) { +>inner3 : Symbol(inner3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 77, 39)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 78, 18)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 78, 21)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 78, 18)) + + return [cb(), cb2()]; +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 77, 25)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 78, 21)) + } + return inner3; +>inner3 : Symbol(inner3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 77, 39)) +} +const nestedResult3 = outer3(() => 1)(() => "foo"); +>nestedResult3 : Symbol(nestedResult3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 83, 5)) +>outer3 : Symbol(outer3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 75, 51)) + +declare function overloaded1(cb: () => T): T; +>overloaded1 : Symbol(overloaded1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 83, 51), Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 29)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 38)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 29)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 29)) + +declare function overloaded1(cb: () => T, cb2: () => U): [T, U]; +>overloaded1 : Symbol(overloaded1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 83, 51), Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 37)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 47)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 29)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 59)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 37)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 86, 37)) + +const overloadA = overloaded1(() => 42); +>overloadA : Symbol(overloadA, Decl(typeParameterConstModifiersReturnsAndYields.ts, 87, 5)) +>overloaded1 : Symbol(overloaded1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 83, 51), Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 54)) + +const overloadB = overloaded1(() => "hi", () => true); +>overloadB : Symbol(overloadB, Decl(typeParameterConstModifiersReturnsAndYields.ts, 88, 5)) +>overloaded1 : Symbol(overloaded1, Decl(typeParameterConstModifiersReturnsAndYields.ts, 83, 51), Decl(typeParameterConstModifiersReturnsAndYields.ts, 85, 54)) + +declare function overloaded2(cb: () => T): T; +>overloaded2 : Symbol(overloaded2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 88, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 48)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 29)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 32)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 29)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 29)) + +declare function overloaded2(cb: () => T, cb2: () => U): [T, U]; +>overloaded2 : Symbol(overloaded2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 88, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 48)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 31)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 41)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 29)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 53)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 31)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 91, 31)) + +const overloadC = overloaded2(() => 42); +>overloadC : Symbol(overloadC, Decl(typeParameterConstModifiersReturnsAndYields.ts, 92, 5)) +>overloaded2 : Symbol(overloaded2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 88, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 48)) + +const overloadD = overloaded2(() => "hi", () => true); +>overloadD : Symbol(overloadD, Decl(typeParameterConstModifiersReturnsAndYields.ts, 93, 5)) +>overloaded2 : Symbol(overloaded2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 88, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 90, 48)) + +declare function overloaded3(cb: () => T): T; +>overloaded3 : Symbol(overloaded3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 93, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 29)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 38)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 29)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 29)) + +declare function overloaded3(cb: () => T, cb2: () => U): [T, U]; +>overloaded3 : Symbol(overloaded3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 93, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 37)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 41)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 29)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 53)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 37)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 96, 37)) + +const overloadE = overloaded3(() => 42); +>overloadE : Symbol(overloadE, Decl(typeParameterConstModifiersReturnsAndYields.ts, 97, 5)) +>overloaded3 : Symbol(overloaded3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 93, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 54)) + +const overloadF = overloaded3(() => "hi", () => true); +>overloadF : Symbol(overloadF, Decl(typeParameterConstModifiersReturnsAndYields.ts, 98, 5)) +>overloaded3 : Symbol(overloaded3, Decl(typeParameterConstModifiersReturnsAndYields.ts, 93, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 95, 54)) + +declare function overloaded4(cb: () => T): T; +>overloaded4 : Symbol(overloaded4, Decl(typeParameterConstModifiersReturnsAndYields.ts, 98, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 29)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 38)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 29)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 29)) + +declare function overloaded4(cb: () => T, cb2: () => U): [T, U]; +>overloaded4 : Symbol(overloaded4, Decl(typeParameterConstModifiersReturnsAndYields.ts, 98, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 54)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 31)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 35)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 29)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 47)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 31)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 101, 31)) + +const overloadG = overloaded4(() => 42); +>overloadG : Symbol(overloadG, Decl(typeParameterConstModifiersReturnsAndYields.ts, 102, 5)) +>overloaded4 : Symbol(overloaded4, Decl(typeParameterConstModifiersReturnsAndYields.ts, 98, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 54)) + +const overloadH = overloaded4(() => "hi", () => true); +>overloadH : Symbol(overloadH, Decl(typeParameterConstModifiersReturnsAndYields.ts, 103, 5)) +>overloaded4 : Symbol(overloaded4, Decl(typeParameterConstModifiersReturnsAndYields.ts, 98, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 100, 54)) + +declare function overloaded5(cb: () => T): T; +>overloaded5 : Symbol(overloaded5, Decl(typeParameterConstModifiersReturnsAndYields.ts, 103, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 48)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 29)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 32)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 29)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 29)) + +declare function overloaded5(cb: () => T, cb2: () => U): [T, U]; +>overloaded5 : Symbol(overloaded5, Decl(typeParameterConstModifiersReturnsAndYields.ts, 103, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 48)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 37)) +>cb : Symbol(cb, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 41)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 29)) +>cb2 : Symbol(cb2, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 53)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 37)) +>T : Symbol(T, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 29)) +>U : Symbol(U, Decl(typeParameterConstModifiersReturnsAndYields.ts, 106, 37)) + +const overloadI = overloaded5(() => 42); +>overloadI : Symbol(overloadI, Decl(typeParameterConstModifiersReturnsAndYields.ts, 107, 5)) +>overloaded5 : Symbol(overloaded5, Decl(typeParameterConstModifiersReturnsAndYields.ts, 103, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 48)) + +const overloadJ = overloaded5(() => "hi", () => true); +>overloadJ : Symbol(overloadJ, Decl(typeParameterConstModifiersReturnsAndYields.ts, 108, 5)) +>overloaded5 : Symbol(overloaded5, Decl(typeParameterConstModifiersReturnsAndYields.ts, 103, 54), Decl(typeParameterConstModifiersReturnsAndYields.ts, 105, 48)) + diff --git a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types index c0a1dfcf503b7..e5355c2453066 100644 --- a/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types @@ -1,256 +1,768 @@ //// [tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts] //// +=== Performance Stats === +Type Count: 2,500 +Instantiation count: 2,500 + === typeParameterConstModifiersReturnsAndYields.ts === enum E { Val, Val2 } >E : E +> : ^ >Val : E.Val +> : ^^^^^ >Val2 : E.Val2 +> : ^^^^^^ declare function test1(create: () => T): T; >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >create : () => T +> : ^^^^^^ const result1 = test1(() => ['a']); >result1 : readonly ["a"] +> : ^^^^^^^^^^^^^^ >test1(() => ['a']) : readonly ["a"] +> : ^^^^^^^^^^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => ['a'] : () => readonly ["a"] +> : ^^^^^^^^^^^^^^^^^^^^ >['a'] : ["a"] +> : ^^^^^ >'a' : "a" +> : ^^^ const result2 = test1(() => `a${Math.random()}`); >result2 : `a${number}` +> : ^^^^^^^^^^^^ >test1(() => `a${Math.random()}`) : `a${number}` +> : ^^^^^^^^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => `a${Math.random()}` : () => `a${number}` +> : ^^^^^^^^^^^^^^^^^^ >`a${Math.random()}` : `a${number}` +> : ^^^^^^^^^^^^ >Math.random() : number +> : ^^^^^^ >Math.random : () => number +> : ^^^^^^ >Math : Math +> : ^^^^ >random : () => number +> : ^^^^^^ const result3 = test1(() => 'a'); >result3 : "a" +> : ^^^ >test1(() => 'a') : "a" +> : ^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => 'a' : () => "a" +> : ^^^^^^^^^ >'a' : "a" +> : ^^^ const result4 = test1(() => true); >result4 : true +> : ^^^^ >test1(() => true) : true +> : ^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => true : () => true +> : ^^^^^^^^^^ >true : true +> : ^^^^ const result5 = test1(() => 101n); >result5 : 101n +> : ^^^^ >test1(() => 101n) : 101n +> : ^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => 101n : () => 101n +> : ^^^^^^^^^^ >101n : 101n +> : ^^^^ const result6 = test1(() => false); >result6 : false +> : ^^^^^ >test1(() => false) : false +> : ^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => false : () => false +> : ^^^^^^^^^^^ >false : false +> : ^^^^^ const result7 = test1(() => 11111); >result7 : 11111 +> : ^^^^^ >test1(() => 11111) : 11111 +> : ^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => 11111 : () => 11111 +> : ^^^^^^^^^^^ >11111 : 11111 +> : ^^^^^ const result8 = test1(() => E.Val); >result8 : E.Val +> : ^^^^^ >test1(() => E.Val) : E.Val +> : ^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => E.Val : () => E.Val +> : ^^^^^^^^^^^ >E.Val : E.Val +> : ^^^^^ >E : typeof E +> : ^^^^^^^^ >Val : E.Val +> : ^^^^^ const result9 = test1(() => { return ['a']; }); >result9 : readonly ["a"] +> : ^^^^^^^^^^^^^^ >test1(() => { return ['a']; }) : readonly ["a"] +> : ^^^^^^^^^^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return ['a']; } : () => readonly ["a"] +> : ^^^^^^^^^^^^^^^^^^^^ >['a'] : ["a"] +> : ^^^^^ >'a' : "a" +> : ^^^ const result10 = test1(() => { return `a${Math.random()}`; }); >result10 : `a${number}` +> : ^^^^^^^^^^^^ >test1(() => { return `a${Math.random()}`; }) : `a${number}` +> : ^^^^^^^^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return `a${Math.random()}`; } : () => `a${number}` +> : ^^^^^^^^^^^^^^^^^^ >`a${Math.random()}` : `a${number}` +> : ^^^^^^^^^^^^ >Math.random() : number +> : ^^^^^^ >Math.random : () => number +> : ^^^^^^ >Math : Math +> : ^^^^ >random : () => number +> : ^^^^^^ const result11 = test1(() => { return 'a'; }); >result11 : "a" +> : ^^^ >test1(() => { return 'a'; }) : "a" +> : ^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return 'a'; } : () => "a" +> : ^^^^^^^^^ >'a' : "a" +> : ^^^ const result12 = test1(() => { return true; }); >result12 : true +> : ^^^^ >test1(() => { return true; }) : true +> : ^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return true; } : () => true +> : ^^^^^^^^^^ >true : true +> : ^^^^ const result13 = test1(() => { return 101n; }); >result13 : 101n +> : ^^^^ >test1(() => { return 101n; }) : 101n +> : ^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return 101n; } : () => 101n +> : ^^^^^^^^^^ >101n : 101n +> : ^^^^ const result14 = test1(() => { return false; }); >result14 : false +> : ^^^^^ >test1(() => { return false; }) : false +> : ^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return false; } : () => false +> : ^^^^^^^^^^^ >false : false +> : ^^^^^ const result15 = test1(() => { return 11111; }); >result15 : 11111 +> : ^^^^^ >test1(() => { return 11111; }) : 11111 +> : ^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return 11111; } : () => 11111 +> : ^^^^^^^^^^^ >11111 : 11111 +> : ^^^^^ const result16 = test1(() => { return E.Val; }); >result16 : E.Val +> : ^^^^^ >test1(() => { return E.Val; }) : E.Val +> : ^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >() => { return E.Val; } : () => E.Val +> : ^^^^^^^^^^^ >E.Val : E.Val +> : ^^^^^ >E : typeof E +> : ^^^^^^^^ >Val : E.Val +> : ^^^^^ const result17 = test1(async () => 'foo'); >result17 : Promise<"foo"> +> : ^^^^^^^^^^^^^^ >test1(async () => 'foo') : Promise<"foo"> +> : ^^^^^^^^^^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >async () => 'foo' : () => Promise<"foo"> +> : ^^^^^^^^^^^^^^^^^^^^ >'foo' : "foo" +> : ^^^^^ const result18 = test1(async () => { return 'foo'; }); >result18 : Promise<"foo"> +> : ^^^^^^^^^^^^^^ >test1(async () => { return 'foo'; }) : Promise<"foo"> +> : ^^^^^^^^^^^^^^ >test1 : (create: () => T) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >async () => { return 'foo'; } : () => Promise<"foo"> +> : ^^^^^^^^^^^^^^^^^^^^ >'foo' : "foo" +> : ^^^^^ declare function test2(create: () => Promise): T; >test2 : (create: () => Promise) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >create : () => Promise +> : ^^^^^^ const result19 = test2(async () => 'foo'); >result19 : "foo" +> : ^^^^^ >test2(async () => 'foo') : "foo" +> : ^^^^^ >test2 : (create: () => Promise) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >async () => 'foo' : () => Promise<"foo"> +> : ^^^^^^^^^^^^^^^^^^^^ >'foo' : "foo" +> : ^^^^^ const result20 = test2(async () => { return 'foo'; }); >result20 : "foo" +> : ^^^^^ >test2(async () => { return 'foo'; }) : "foo" +> : ^^^^^ >test2 : (create: () => Promise) => T +> : ^^^^^^^ ^^ ^^ ^^^^^ >async () => { return 'foo'; } : () => Promise<"foo"> +> : ^^^^^^^^^^^^^^^^^^^^ >'foo' : "foo" +> : ^^^^^ declare function test3(arg: () => Generator): [T, R] >test3 : (arg: () => Generator) => [T, R] +> : ^^^^^^^ ^^^^^^^^ ^^ ^^ ^^^^^ >arg : () => Generator +> : ^^^^^^ const result21 = test3(function*() { >result21 : [10, "1"] +> : ^^^^^^^^^ >test3(function*() { yield 10; return '1';}) : [10, "1"] ->test3 : (arg: () => Generator) => [T, R] ->function*() { yield 10; return '1';} : () => Generator<10, "1", unknown> +> : ^^^^^^^^^ +>test3 : (arg: () => Generator) => [T, R] +> : ^^^^^^^ ^^^^^^^^ ^^ ^^ ^^^^^ +>function*() { yield 10; return '1';} : () => Generator<10, "1", any> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ yield 10; ->yield 10 : unknown +>yield 10 : any >10 : 10 +> : ^^ return '1'; >'1' : "1" +> : ^^^ }); declare function test4(arg: () => AsyncGenerator): [T, R] >test4 : (arg: () => AsyncGenerator) => [T, R] +> : ^^^^^^^ ^^^^^^^^ ^^ ^^ ^^^^^ >arg : () => AsyncGenerator +> : ^^^^^^ const result22 = test4(async function*() { >result22 : [10, "1"] +> : ^^^^^^^^^ >test4(async function*() { yield 10; return '1';}) : [10, "1"] ->test4 : (arg: () => AsyncGenerator) => [T, R] ->async function*() { yield 10; return '1';} : () => AsyncGenerator<10, "1", unknown> +> : ^^^^^^^^^ +>test4 : (arg: () => AsyncGenerator) => [T, R] +> : ^^^^^^^ ^^^^^^^^ ^^ ^^ ^^^^^ +>async function*() { yield 10; return '1';} : () => AsyncGenerator<10, "1", any> +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ yield 10; ->yield 10 : unknown +>yield 10 : any >10 : 10 +> : ^^ return '1'; >'1' : "1" +> : ^^^ }); // https://github.com/microsoft/TypeScript/issues/53813 const UploadThingServerHelper = (route: { >UploadThingServerHelper : (route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; }) => void +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^ >(route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route] }) => void; };}) => {} : (route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; }) => void +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^ >route : { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; } +> : ^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^ readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; >middleware : () => ValidRoutes[Route] +> : ^^^^^^ onUpload: (response: { metadata: ValidRoutes[Route] }) => void; ->onUpload : (response: { metadata: ValidRoutes[Route];}) => void +>onUpload : (response: { metadata: ValidRoutes[Route]; }) => void +> : ^ ^^ ^^^^^ >response : { metadata: ValidRoutes[Route]; } +> : ^^^^^^^^^^^^ ^^^ >metadata : ValidRoutes[Route] +> : ^^^^^^^^^^^^^^^^^^ }; }) => {}; const FileRouter = UploadThingServerHelper({ >FileRouter : void +> : ^^^^ >UploadThingServerHelper({ example: { middleware: () => "someValue", onUpload: (response) => { const v: "someValue" = response.metadata; }, },}) : void +> : ^^^^ >UploadThingServerHelper : (route: { readonly [Route in keyof ValidRoutes]: { middleware: () => ValidRoutes[Route]; onUpload: (response: { metadata: ValidRoutes[Route]; }) => void; }; }) => void +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^ >{ example: { middleware: () => "someValue", onUpload: (response) => { const v: "someValue" = response.metadata; }, },} : { example: { middleware: () => "someValue"; onUpload: (response: { metadata: "someValue"; }) => void; }; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ example: { >example : { middleware: () => "someValue"; onUpload: (response: { metadata: "someValue"; }) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >{ middleware: () => "someValue", onUpload: (response) => { const v: "someValue" = response.metadata; }, } : { middleware: () => "someValue"; onUpload: (response: { metadata: "someValue"; }) => void; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ middleware: () => "someValue", >middleware : () => "someValue" +> : ^^^^^^^^^^^^^^^^^ >() => "someValue" : () => "someValue" +> : ^^^^^^^^^^^^^^^^^ >"someValue" : "someValue" +> : ^^^^^^^^^^^ onUpload: (response) => { >onUpload : (response: { metadata: "someValue"; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >(response) => { const v: "someValue" = response.metadata; } : (response: { metadata: "someValue"; }) => void +> : ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ >response : { metadata: "someValue"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ const v: "someValue" = response.metadata; >v : "someValue" +> : ^^^^^^^^^^^ >response.metadata : "someValue" +> : ^^^^^^^^^^^ >response : { metadata: "someValue"; } +> : ^^^^^^^^^^^^^^^^^^^^^^^^^^ >metadata : "someValue" +> : ^^^^^^^^^^^ }, }, }); +function outer1(cb: () => T) { +>outer1 : (cb: () => T) => (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>cb : () => T +> : ^^^^^^ + + function inner1(cb2: () => U) { +>inner1 : (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>cb2 : () => U +> : ^^^^^^ + + return [cb(), cb2()]; +>[cb(), cb2()] : (T | U)[] +> : ^^^^^^^^^ +>cb() : T +> : ^ +>cb : () => T +> : ^^^^^^ +>cb2() : U +> : ^ +>cb2 : () => U +> : ^^^^^^ + } + return inner1; +>inner1 : (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +} +const nestedResult1 = outer1(() => 1)(() => "foo"); +>nestedResult1 : (1 | "foo")[] +> : ^^^^^^^^^^^^^ +>outer1(() => 1)(() => "foo") : (1 | "foo")[] +> : ^^^^^^^^^^^^^ +>outer1(() => 1) : (cb2: () => U) => (1 | U)[] +> : ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^ +>outer1 : (cb: () => T) => (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>() => 1 : () => 1 +> : ^^^^^^^ +>1 : 1 +> : ^ +>() => "foo" : () => "foo" +> : ^^^^^^^^^^^ +>"foo" : "foo" +> : ^^^^^ + +function outer2(cb: () => T) { +>outer2 : (cb: () => T) => (cb2: () => U) => (T | U)[] +> : ^ ^^ ^^ ^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>cb : () => T +> : ^^^^^^ + + function inner2(cb2: () => U) { +>inner2 : (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>cb2 : () => U +> : ^^^^^^ + + return [cb(), cb2()]; +>[cb(), cb2()] : (T | U)[] +> : ^^^^^^^^^ +>cb() : T +> : ^ +>cb : () => T +> : ^^^^^^ +>cb2() : U +> : ^ +>cb2 : () => U +> : ^^^^^^ + } + return inner2; +>inner2 : (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +} +const nestedResult2 = outer2(() => 1)(() => "foo"); +>nestedResult2 : (number | "foo")[] +> : ^^^^^^^^^^^^^^^^^^ +>outer2(() => 1)(() => "foo") : (number | "foo")[] +> : ^^^^^^^^^^^^^^^^^^ +>outer2(() => 1) : (cb2: () => U) => (number | U)[] +> : ^^^^^^^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +>outer2 : (cb: () => T) => (cb2: () => U) => (T | U)[] +> : ^ ^^ ^^ ^^^^^^^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>() => 1 : () => number +> : ^^^^^^^^^^^^ +>1 : 1 +> : ^ +>() => "foo" : () => "foo" +> : ^^^^^^^^^^^ +>"foo" : "foo" +> : ^^^^^ + +function outer3(cb: () => T) { +>outer3 : (cb: () => T) => (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>cb : () => T +> : ^^^^^^ + + function inner3(cb2: () => U) { +>inner3 : (cb2: () => U) => (T | U)[] +> : ^ ^^ ^^ ^^^^^^^^^^^^^^ +>cb2 : () => U +> : ^^^^^^ + + return [cb(), cb2()]; +>[cb(), cb2()] : (T | U)[] +> : ^^^^^^^^^ +>cb() : T +> : ^ +>cb : () => T +> : ^^^^^^ +>cb2() : U +> : ^ +>cb2 : () => U +> : ^^^^^^ + } + return inner3; +>inner3 : (cb2: () => U) => (T | U)[] +> : ^ ^^ ^^ ^^^^^^^^^^^^^^ +} +const nestedResult3 = outer3(() => 1)(() => "foo"); +>nestedResult3 : (string | 1)[] +> : ^^^^^^^^^^^^^^ +>outer3(() => 1)(() => "foo") : (string | 1)[] +> : ^^^^^^^^^^^^^^ +>outer3(() => 1) : (cb2: () => U) => (1 | U)[] +> : ^ ^^ ^^^^^^^^^^^^^^^^^^^^^^^ +>outer3 : (cb: () => T) => (cb2: () => U) => (T | U)[] +> : ^^^^^^^ ^^ ^^ ^^^^^^ ^^ ^^ ^^^^^^^^^^^^^^ +>() => 1 : () => 1 +> : ^^^^^^^ +>1 : 1 +> : ^ +>() => "foo" : () => string +> : ^^^^^^^^^^^^ +>"foo" : "foo" +> : ^^^^^ + +declare function overloaded1(cb: () => T): T; +>overloaded1 : { (cb: () => T): T; (cb: () => T_1, cb2: () => U): [T_1, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^^^^^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ + +declare function overloaded1(cb: () => T, cb2: () => U): [T, U]; +>overloaded1 : { (cb: () => T_1): T_1; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^^^^^^ ^^ ^^^ ^^^^^^^^^ ^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ +>cb2 : () => U +> : ^^^^^^ + +const overloadA = overloaded1(() => 42); +>overloadA : 42 +> : ^^ +>overloaded1(() => 42) : 42 +> : ^^ +>overloaded1 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^^^^^^^ ^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => 42 : () => 42 +> : ^^^^^^^^ +>42 : 42 +> : ^^ + +const overloadB = overloaded1(() => "hi", () => true); +>overloadB : ["hi", true] +> : ^^^^^^^^^^^^ +>overloaded1(() => "hi", () => true) : ["hi", true] +> : ^^^^^^^^^^^^ +>overloaded1 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^^^^^^^ ^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => "hi" : () => "hi" +> : ^^^^^^^^^^ +>"hi" : "hi" +> : ^^^^ +>() => true : () => true +> : ^^^^^^^^^^ +>true : true +> : ^^^^ + +declare function overloaded2(cb: () => T): T; +>overloaded2 : { (cb: () => T): T; (cb: () => T_1, cb2: () => U): [T_1, U]; } +> : ^^^ ^^ ^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ + +declare function overloaded2(cb: () => T, cb2: () => U): [T, U]; +>overloaded2 : { (cb: () => T_1): T_1; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^ ^^ ^^^ ^^^ ^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ +>cb2 : () => U +> : ^^^^^^ + +const overloadC = overloaded2(() => 42); +>overloadC : number +> : ^^^^^^ +>overloaded2(() => 42) : number +> : ^^^^^^ +>overloaded2 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => 42 : () => number +> : ^^^^^^^^^^^^ +>42 : 42 +> : ^^ + +const overloadD = overloaded2(() => "hi", () => true); +>overloadD : [string, true] +> : ^^^^^^^^^^^^^^ +>overloaded2(() => "hi", () => true) : [string, true] +> : ^^^^^^^^^^^^^^ +>overloaded2 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^ ^^ ^^ ^^^ ^^^ ^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => "hi" : () => string +> : ^^^^^^^^^^^^ +>"hi" : "hi" +> : ^^^^ +>() => true : () => true +> : ^^^^^^^^^^ +>true : true +> : ^^^^ + +declare function overloaded3(cb: () => T): T; +>overloaded3 : { (cb: () => T): T; (cb: () => T_1, cb2: () => U): [T_1, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ + +declare function overloaded3(cb: () => T, cb2: () => U): [T, U]; +>overloaded3 : { (cb: () => T_1): T_1; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^^^^^^ ^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ +>cb2 : () => U +> : ^^^^^^ + +const overloadE = overloaded3(() => 42); +>overloadE : 42 +> : ^^ +>overloaded3(() => 42) : 42 +> : ^^ +>overloaded3 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => 42 : () => 42 +> : ^^^^^^^^ +>42 : 42 +> : ^^ + +const overloadF = overloaded3(() => "hi", () => true); +>overloadF : ["hi", boolean] +> : ^^^^^^^^^^^^^^^ +>overloaded3(() => "hi", () => true) : ["hi", boolean] +> : ^^^^^^^^^^^^^^^ +>overloaded3 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => "hi" : () => "hi" +> : ^^^^^^^^^^ +>"hi" : "hi" +> : ^^^^ +>() => true : () => boolean +> : ^^^^^^^^^^^^^ +>true : true +> : ^^^^ + +declare function overloaded4(cb: () => T): T; +>overloaded4 : { (cb: () => T): T; (cb: () => T_1, cb2: () => U): [T_1, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ + +declare function overloaded4(cb: () => T, cb2: () => U): [T, U]; +>overloaded4 : { (cb: () => T_1): T_1; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^^^^^^ ^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ +>cb2 : () => U +> : ^^^^^^ + +const overloadG = overloaded4(() => 42); +>overloadG : 42 +> : ^^ +>overloaded4(() => 42) : 42 +> : ^^ +>overloaded4 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => 42 : () => 42 +> : ^^^^^^^^ +>42 : 42 +> : ^^ + +const overloadH = overloaded4(() => "hi", () => true); +>overloadH : [string, boolean] +> : ^^^^^^^^^^^^^^^^^ +>overloaded4(() => "hi", () => true) : [string, boolean] +> : ^^^^^^^^^^^^^^^^^ +>overloaded4 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^^ ^^ ^^ ^^^ ^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => "hi" : () => string +> : ^^^^^^^^^^^^ +>"hi" : "hi" +> : ^^^^ +>() => true : () => boolean +> : ^^^^^^^^^^^^^ +>true : true +> : ^^^^ + +declare function overloaded5(cb: () => T): T; +>overloaded5 : { (cb: () => T): T; (cb: () => T_1, cb2: () => U): [T_1, U]; } +> : ^^^ ^^ ^^ ^^^ ^^^^^^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ + +declare function overloaded5(cb: () => T, cb2: () => U): [T, U]; +>overloaded5 : { (cb: () => T_1): T_1; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^^^^^^ ^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>cb : () => T +> : ^^^^^^ +>cb2 : () => U +> : ^^^^^^ + +const overloadI = overloaded5(() => 42); +>overloadI : number +> : ^^^^^^ +>overloaded5(() => 42) : number +> : ^^^^^^ +>overloaded5 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^ ^^ ^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => 42 : () => number +> : ^^^^^^^^^^^^ +>42 : 42 +> : ^^ + +const overloadJ = overloaded5(() => "hi", () => true); +>overloadJ : ["hi", boolean] +> : ^^^^^^^^^^^^^^^ +>overloaded5(() => "hi", () => true) : ["hi", boolean] +> : ^^^^^^^^^^^^^^^ +>overloaded5 : { (cb: () => T): T; (cb: () => T, cb2: () => U): [T, U]; } +> : ^^^ ^^ ^^ ^^^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^^ ^^^ +>() => "hi" : () => "hi" +> : ^^^^^^^^^^ +>"hi" : "hi" +> : ^^^^ +>() => true : () => boolean +> : ^^^^^^^^^^^^^ +>true : true +> : ^^^^ + diff --git a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts index ed2f6ccaccde8..f96abd5f5daac 100644 --- a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts @@ -62,3 +62,52 @@ const FileRouter = UploadThingServerHelper({ }, }, }); + +function outer1(cb: () => T) { + function inner1(cb2: () => U) { + return [cb(), cb2()]; + } + return inner1; +} +const nestedResult1 = outer1(() => 1)(() => "foo"); + +function outer2(cb: () => T) { + function inner2(cb2: () => U) { + return [cb(), cb2()]; + } + return inner2; +} +const nestedResult2 = outer2(() => 1)(() => "foo"); + +function outer3(cb: () => T) { + function inner3(cb2: () => U) { + return [cb(), cb2()]; + } + return inner3; +} +const nestedResult3 = outer3(() => 1)(() => "foo"); + +declare function overloaded1(cb: () => T): T; +declare function overloaded1(cb: () => T, cb2: () => U): [T, U]; +const overloadA = overloaded1(() => 42); +const overloadB = overloaded1(() => "hi", () => true); + +declare function overloaded2(cb: () => T): T; +declare function overloaded2(cb: () => T, cb2: () => U): [T, U]; +const overloadC = overloaded2(() => 42); +const overloadD = overloaded2(() => "hi", () => true); + +declare function overloaded3(cb: () => T): T; +declare function overloaded3(cb: () => T, cb2: () => U): [T, U]; +const overloadE = overloaded3(() => 42); +const overloadF = overloaded3(() => "hi", () => true); + +declare function overloaded4(cb: () => T): T; +declare function overloaded4(cb: () => T, cb2: () => U): [T, U]; +const overloadG = overloaded4(() => 42); +const overloadH = overloaded4(() => "hi", () => true); + +declare function overloaded5(cb: () => T): T; +declare function overloaded5(cb: () => T, cb2: () => U): [T, U]; +const overloadI = overloaded5(() => 42); +const overloadJ = overloaded5(() => "hi", () => true);