diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 30c41c94d3aa1..6eead24f09192 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -36851,6 +36851,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 @@ -36977,7 +36980,10 @@ 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; + 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) { @@ -37100,7 +37106,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..9127ede3b0723 --- /dev/null +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.symbols @@ -0,0 +1,202 @@ +//// [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'; +}); + +// 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 new file mode 100644 index 0000000000000..c0a1dfcf503b7 --- /dev/null +++ b/tests/baselines/reference/typeParameterConstModifiersReturnsAndYields.types @@ -0,0 +1,256 @@ +//// [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" + +}); + +// 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 new file mode 100644 index 0000000000000..ed2f6ccaccde8 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiersReturnsAndYields.ts @@ -0,0 +1,64 @@ +// @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'; +}); + +// 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; + }, + }, +});