diff --git a/tests/baselines/reference/typeParameterConstModifiers.errors.txt b/tests/baselines/reference/typeParameterConstModifiers.errors.txt index 872f0fe8910a2..c46be5e6f26e6 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.errors.txt +++ b/tests/baselines/reference/typeParameterConstModifiers.errors.txt @@ -130,4 +130,53 @@ typeParameterConstModifiers.ts(55,9): error TS1277: 'const' modifier can only ap const t2_55033 = factory_55033((a: { test: number }, b: string) => {})( { test: 123 } as const, "some string" - ); \ No newline at end of file + ); + + // Same with non-readonly constraint + + function factory_55033_2(cb: (...args: T) => void) { + return function call(...args: K): K { + return {} as K; + }; + } + + const t1_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( + { test: 123 }, + "some string" + ); + + const t2_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( + { test: 123 } as const, + "some string" + ); + + // Repro from https://github.com/microsoft/TypeScript/issues/51931 + + declare function fn(...args: T): T; + + const a = fn("a", false); + + // More examples of non-readonly constraints + + declare function fa1(args: T): T; + declare function fa2(args: T): T; + + fa1(["hello", 42]); + fa2(["hello", 42]); + + declare function fb1(...args: T): T; + declare function fb2(...args: T): T; + + fb1("hello", 42); + fb2("hello", 42); + + declare function fc1(f: (...args: T) => void, ...args: T): T; + declare function fc2(f: (...args: T) => void, ...args: T): T; + + fc1((a: string, b: number) => {}, "hello", 42); + fc2((a: string, b: number) => {}, "hello", 42); + + declare function fn1(...args: T): T; + + fn1({ foo: ["hello", 123] }, { foo: [true]}); + \ No newline at end of file diff --git a/tests/baselines/reference/typeParameterConstModifiers.js b/tests/baselines/reference/typeParameterConstModifiers.js index b52cded2b902d..367f176c7274a 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.js +++ b/tests/baselines/reference/typeParameterConstModifiers.js @@ -124,7 +124,56 @@ const t1_55033 = factory_55033((a: { test: number }, b: string) => {})( const t2_55033 = factory_55033((a: { test: number }, b: string) => {})( { test: 123 } as const, "some string" -); +); + +// Same with non-readonly constraint + +function factory_55033_2(cb: (...args: T) => void) { + return function call(...args: K): K { + return {} as K; + }; +} + +const t1_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( + { test: 123 }, + "some string" +); + +const t2_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( + { test: 123 } as const, + "some string" +); + +// Repro from https://github.com/microsoft/TypeScript/issues/51931 + +declare function fn(...args: T): T; + +const a = fn("a", false); + +// More examples of non-readonly constraints + +declare function fa1(args: T): T; +declare function fa2(args: T): T; + +fa1(["hello", 42]); +fa2(["hello", 42]); + +declare function fb1(...args: T): T; +declare function fb2(...args: T): T; + +fb1("hello", 42); +fb2("hello", 42); + +declare function fc1(f: (...args: T) => void, ...args: T): T; +declare function fc2(f: (...args: T) => void, ...args: T): T; + +fc1((a: string, b: number) => {}, "hello", 42); +fc2((a: string, b: number) => {}, "hello", 42); + +declare function fn1(...args: T): T; + +fn1({ foo: ["hello", 123] }, { foo: [true]}); + //// [typeParameterConstModifiers.js] "use strict"; @@ -193,3 +242,23 @@ function factory_55033(cb) { } var t1_55033 = factory_55033(function (a, b) { })({ test: 123 }, "some string"); var t2_55033 = factory_55033(function (a, b) { })({ test: 123 }, "some string"); +// Same with non-readonly constraint +function factory_55033_2(cb) { + return function call() { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return {}; + }; +} +var t1_55033_2 = factory_55033_2(function (a, b) { })({ test: 123 }, "some string"); +var t2_55033_2 = factory_55033_2(function (a, b) { })({ test: 123 }, "some string"); +var a = fn("a", false); +fa1(["hello", 42]); +fa2(["hello", 42]); +fb1("hello", 42); +fb2("hello", 42); +fc1(function (a, b) { }, "hello", 42); +fc2(function (a, b) { }, "hello", 42); +fn1({ foo: ["hello", 123] }, { foo: [true] }); diff --git a/tests/baselines/reference/typeParameterConstModifiers.symbols b/tests/baselines/reference/typeParameterConstModifiers.symbols index 371a38201488f..160a354a105e5 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.symbols +++ b/tests/baselines/reference/typeParameterConstModifiers.symbols @@ -426,3 +426,152 @@ const t2_55033 = factory_55033((a: { test: number }, b: string) => {})( "some string" ); + +// Same with non-readonly constraint + +function factory_55033_2(cb: (...args: T) => void) { +>factory_55033_2 : Symbol(factory_55033_2, Decl(typeParameterConstModifiers.ts, 123, 2)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 127, 25)) +>cb : Symbol(cb, Decl(typeParameterConstModifiers.ts, 127, 52)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 127, 57)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 127, 25)) + + return function call(...args: K): K { +>call : Symbol(call, Decl(typeParameterConstModifiers.ts, 128, 10)) +>K : Symbol(K, Decl(typeParameterConstModifiers.ts, 128, 25)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 127, 25)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 128, 44)) +>K : Symbol(K, Decl(typeParameterConstModifiers.ts, 128, 25)) +>K : Symbol(K, Decl(typeParameterConstModifiers.ts, 128, 25)) + + return {} as K; +>K : Symbol(K, Decl(typeParameterConstModifiers.ts, 128, 25)) + + }; +} + +const t1_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( +>t1_55033_2 : Symbol(t1_55033_2, Decl(typeParameterConstModifiers.ts, 133, 5)) +>factory_55033_2 : Symbol(factory_55033_2, Decl(typeParameterConstModifiers.ts, 123, 2)) +>a : Symbol(a, Decl(typeParameterConstModifiers.ts, 133, 36)) +>test : Symbol(test, Decl(typeParameterConstModifiers.ts, 133, 40)) +>b : Symbol(b, Decl(typeParameterConstModifiers.ts, 133, 56)) + + { test: 123 }, +>test : Symbol(test, Decl(typeParameterConstModifiers.ts, 134, 5)) + + "some string" +); + +const t2_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( +>t2_55033_2 : Symbol(t2_55033_2, Decl(typeParameterConstModifiers.ts, 138, 5)) +>factory_55033_2 : Symbol(factory_55033_2, Decl(typeParameterConstModifiers.ts, 123, 2)) +>a : Symbol(a, Decl(typeParameterConstModifiers.ts, 138, 36)) +>test : Symbol(test, Decl(typeParameterConstModifiers.ts, 138, 40)) +>b : Symbol(b, Decl(typeParameterConstModifiers.ts, 138, 56)) + + { test: 123 } as const, +>test : Symbol(test, Decl(typeParameterConstModifiers.ts, 139, 5)) +>const : Symbol(const) + + "some string" +); + +// Repro from https://github.com/microsoft/TypeScript/issues/51931 + +declare function fn(...args: T): T; +>fn : Symbol(fn, Decl(typeParameterConstModifiers.ts, 141, 2)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 145, 20)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 145, 43)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 145, 20)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 145, 20)) + +const a = fn("a", false); +>a : Symbol(a, Decl(typeParameterConstModifiers.ts, 147, 5)) +>fn : Symbol(fn, Decl(typeParameterConstModifiers.ts, 141, 2)) + +// More examples of non-readonly constraints + +declare function fa1(args: T): T; +>fa1 : Symbol(fa1, Decl(typeParameterConstModifiers.ts, 147, 25)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 151, 21)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 151, 48)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 151, 21)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 151, 21)) + +declare function fa2(args: T): T; +>fa2 : Symbol(fa2, Decl(typeParameterConstModifiers.ts, 151, 60)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 152, 21)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 152, 57)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 152, 21)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 152, 21)) + +fa1(["hello", 42]); +>fa1 : Symbol(fa1, Decl(typeParameterConstModifiers.ts, 147, 25)) + +fa2(["hello", 42]); +>fa2 : Symbol(fa2, Decl(typeParameterConstModifiers.ts, 151, 60)) + +declare function fb1(...args: T): T; +>fb1 : Symbol(fb1, Decl(typeParameterConstModifiers.ts, 155, 19)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 157, 21)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 157, 48)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 157, 21)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 157, 21)) + +declare function fb2(...args: T): T; +>fb2 : Symbol(fb2, Decl(typeParameterConstModifiers.ts, 157, 63)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 158, 21)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 158, 57)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 158, 21)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 158, 21)) + +fb1("hello", 42); +>fb1 : Symbol(fb1, Decl(typeParameterConstModifiers.ts, 155, 19)) + +fb2("hello", 42); +>fb2 : Symbol(fb2, Decl(typeParameterConstModifiers.ts, 157, 63)) + +declare function fc1(f: (...args: T) => void, ...args: T): T; +>fc1 : Symbol(fc1, Decl(typeParameterConstModifiers.ts, 161, 17)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 163, 21)) +>f : Symbol(f, Decl(typeParameterConstModifiers.ts, 163, 48)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 163, 52)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 163, 21)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 163, 72)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 163, 21)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 163, 21)) + +declare function fc2(f: (...args: T) => void, ...args: T): T; +>fc2 : Symbol(fc2, Decl(typeParameterConstModifiers.ts, 163, 88)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 164, 21)) +>f : Symbol(f, Decl(typeParameterConstModifiers.ts, 164, 57)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 164, 61)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 164, 21)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 164, 81)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 164, 21)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 164, 21)) + +fc1((a: string, b: number) => {}, "hello", 42); +>fc1 : Symbol(fc1, Decl(typeParameterConstModifiers.ts, 161, 17)) +>a : Symbol(a, Decl(typeParameterConstModifiers.ts, 166, 5)) +>b : Symbol(b, Decl(typeParameterConstModifiers.ts, 166, 15)) + +fc2((a: string, b: number) => {}, "hello", 42); +>fc2 : Symbol(fc2, Decl(typeParameterConstModifiers.ts, 163, 88)) +>a : Symbol(a, Decl(typeParameterConstModifiers.ts, 167, 5)) +>b : Symbol(b, Decl(typeParameterConstModifiers.ts, 167, 15)) + +declare function fn1(...args: T): T; +>fn1 : Symbol(fn1, Decl(typeParameterConstModifiers.ts, 167, 47)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 169, 21)) +>foo : Symbol(foo, Decl(typeParameterConstModifiers.ts, 169, 38)) +>args : Symbol(args, Decl(typeParameterConstModifiers.ts, 169, 59)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 169, 21)) +>T : Symbol(T, Decl(typeParameterConstModifiers.ts, 169, 21)) + +fn1({ foo: ["hello", 123] }, { foo: [true]}); +>fn1 : Symbol(fn1, Decl(typeParameterConstModifiers.ts, 167, 47)) +>foo : Symbol(foo, Decl(typeParameterConstModifiers.ts, 171, 5)) +>foo : Symbol(foo, Decl(typeParameterConstModifiers.ts, 171, 30)) + diff --git a/tests/baselines/reference/typeParameterConstModifiers.types b/tests/baselines/reference/typeParameterConstModifiers.types index 6c87617c96c9a..37dd7c23df911 100644 --- a/tests/baselines/reference/typeParameterConstModifiers.types +++ b/tests/baselines/reference/typeParameterConstModifiers.types @@ -485,3 +485,169 @@ const t2_55033 = factory_55033((a: { test: number }, b: string) => {})( >"some string" : "some string" ); + +// Same with non-readonly constraint + +function factory_55033_2(cb: (...args: T) => void) { +>factory_55033_2 : (cb: (...args: T) => void) => (...args: K) => K +>cb : (...args: T) => void +>args : T + + return function call(...args: K): K { +>function call(...args: K): K { return {} as K; } : (...args: K) => K +>call : (...args: K) => K +>args : K + + return {} as K; +>{} as K : K +>{} : {} + + }; +} + +const t1_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( +>t1_55033_2 : [{ readonly test: 123; }, "some string"] +>factory_55033_2((a: { test: number }, b: string) => {})( { test: 123 }, "some string") : [{ readonly test: 123; }, "some string"] +>factory_55033_2((a: { test: number }, b: string) => {}) : (...args: K) => K +>factory_55033_2 : (cb: (...args: T) => void) => (...args: K) => K +>(a: { test: number }, b: string) => {} : (a: { test: number;}, b: string) => void +>a : { test: number; } +>test : number +>b : string + + { test: 123 }, +>{ test: 123 } : { test: 123; } +>test : 123 +>123 : 123 + + "some string" +>"some string" : "some string" + +); + +const t2_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( +>t2_55033_2 : [{ readonly test: 123; }, "some string"] +>factory_55033_2((a: { test: number }, b: string) => {})( { test: 123 } as const, "some string") : [{ readonly test: 123; }, "some string"] +>factory_55033_2((a: { test: number }, b: string) => {}) : (...args: K) => K +>factory_55033_2 : (cb: (...args: T) => void) => (...args: K) => K +>(a: { test: number }, b: string) => {} : (a: { test: number;}, b: string) => void +>a : { test: number; } +>test : number +>b : string + + { test: 123 } as const, +>{ test: 123 } as const : { readonly test: 123; } +>{ test: 123 } : { readonly test: 123; } +>test : 123 +>123 : 123 + + "some string" +>"some string" : "some string" + +); + +// Repro from https://github.com/microsoft/TypeScript/issues/51931 + +declare function fn(...args: T): T; +>fn : (...args: T) => T +>args : T + +const a = fn("a", false); +>a : ["a", false] +>fn("a", false) : ["a", false] +>fn : (...args: T) => T +>"a" : "a" +>false : false + +// More examples of non-readonly constraints + +declare function fa1(args: T): T; +>fa1 : (args: T) => T +>args : T + +declare function fa2(args: T): T; +>fa2 : (args: T) => T +>args : T + +fa1(["hello", 42]); +>fa1(["hello", 42]) : ["hello", 42] +>fa1 : (args: T) => T +>["hello", 42] : ["hello", 42] +>"hello" : "hello" +>42 : 42 + +fa2(["hello", 42]); +>fa2(["hello", 42]) : readonly ["hello", 42] +>fa2 : (args: T) => T +>["hello", 42] : ["hello", 42] +>"hello" : "hello" +>42 : 42 + +declare function fb1(...args: T): T; +>fb1 : (...args: T) => T +>args : T + +declare function fb2(...args: T): T; +>fb2 : (...args: T) => T +>args : T + +fb1("hello", 42); +>fb1("hello", 42) : ["hello", 42] +>fb1 : (...args: T) => T +>"hello" : "hello" +>42 : 42 + +fb2("hello", 42); +>fb2("hello", 42) : readonly ["hello", 42] +>fb2 : (...args: T) => T +>"hello" : "hello" +>42 : 42 + +declare function fc1(f: (...args: T) => void, ...args: T): T; +>fc1 : (f: (...args: T) => void, ...args: T) => T +>f : (...args: T) => void +>args : T +>args : T + +declare function fc2(f: (...args: T) => void, ...args: T): T; +>fc2 : (f: (...args: T) => void, ...args: T) => T +>f : (...args: T) => void +>args : T +>args : T + +fc1((a: string, b: number) => {}, "hello", 42); +>fc1((a: string, b: number) => {}, "hello", 42) : ["hello", 42] +>fc1 : (f: (...args: T) => void, ...args: T) => T +>(a: string, b: number) => {} : (a: string, b: number) => void +>a : string +>b : number +>"hello" : "hello" +>42 : 42 + +fc2((a: string, b: number) => {}, "hello", 42); +>fc2((a: string, b: number) => {}, "hello", 42) : readonly ["hello", 42] +>fc2 : (f: (...args: T) => void, ...args: T) => T +>(a: string, b: number) => {} : (a: string, b: number) => void +>a : string +>b : number +>"hello" : "hello" +>42 : 42 + +declare function fn1(...args: T): T; +>fn1 : (...args: T) => T +>foo : unknown[] +>args : T + +fn1({ foo: ["hello", 123] }, { foo: [true]}); +>fn1({ foo: ["hello", 123] }, { foo: [true]}) : [{ readonly foo: ["hello", 123]; }, { readonly foo: [true]; }] +>fn1 : (...args: T) => T +>{ foo: ["hello", 123] } : { foo: ["hello", 123]; } +>foo : ["hello", 123] +>["hello", 123] : ["hello", 123] +>"hello" : "hello" +>123 : 123 +>{ foo: [true]} : { foo: [true]; } +>foo : [true] +>[true] : [true] +>true : true + diff --git a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts index 448f007da972d..6a9e78ff7afad 100644 --- a/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts +++ b/tests/cases/conformance/types/typeParameters/typeParameterLists/typeParameterConstModifiers.ts @@ -123,4 +123,52 @@ const t1_55033 = factory_55033((a: { test: number }, b: string) => {})( const t2_55033 = factory_55033((a: { test: number }, b: string) => {})( { test: 123 } as const, "some string" -); \ No newline at end of file +); + +// Same with non-readonly constraint + +function factory_55033_2(cb: (...args: T) => void) { + return function call(...args: K): K { + return {} as K; + }; +} + +const t1_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( + { test: 123 }, + "some string" +); + +const t2_55033_2 = factory_55033_2((a: { test: number }, b: string) => {})( + { test: 123 } as const, + "some string" +); + +// Repro from https://github.com/microsoft/TypeScript/issues/51931 + +declare function fn(...args: T): T; + +const a = fn("a", false); + +// More examples of non-readonly constraints + +declare function fa1(args: T): T; +declare function fa2(args: T): T; + +fa1(["hello", 42]); +fa2(["hello", 42]); + +declare function fb1(...args: T): T; +declare function fb2(...args: T): T; + +fb1("hello", 42); +fb2("hello", 42); + +declare function fc1(f: (...args: T) => void, ...args: T): T; +declare function fc2(f: (...args: T) => void, ...args: T): T; + +fc1((a: string, b: number) => {}, "hello", 42); +fc2((a: string, b: number) => {}, "hello", 42); + +declare function fn1(...args: T): T; + +fn1({ foo: ["hello", 123] }, { foo: [true]});