From 5eec44a934d7238fe73ab091ce6ea25576651a34 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 14 Mar 2023 13:47:40 -0700 Subject: [PATCH 1/2] Add baselines --- ...xtualTupleTypeParameterReadonly.errors.txt | 32 ++++++++++ .../contextualTupleTypeParameterReadonly.js | 42 ++++++++++++ ...ntextualTupleTypeParameterReadonly.symbols | 55 ++++++++++++++++ ...contextualTupleTypeParameterReadonly.types | 64 +++++++++++++++++++ .../contextualTupleTypeParameterReadonly.ts | 21 ++++++ 5 files changed, 214 insertions(+) create mode 100644 tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt create mode 100644 tests/baselines/reference/contextualTupleTypeParameterReadonly.js create mode 100644 tests/baselines/reference/contextualTupleTypeParameterReadonly.symbols create mode 100644 tests/baselines/reference/contextualTupleTypeParameterReadonly.types create mode 100644 tests/cases/compiler/contextualTupleTypeParameterReadonly.ts diff --git a/tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt b/tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt new file mode 100644 index 0000000000000..2f68bc6125d1e --- /dev/null +++ b/tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt @@ -0,0 +1,32 @@ +tests/cases/compiler/contextualTupleTypeParameterReadonly.ts(10,8): error TS2345: Argument of type '(a: 1 | 2, b: "1" | "2") => void' is not assignable to parameter of type '(...args: readonly [1, "1"] | readonly [2, "2"]) => any'. + Types of parameters 'a' and 'args' are incompatible. + Type 'readonly [1, "1"] | readonly [2, "2"]' is not assignable to type '[a: 1 | 2, b: "1" | "2"]'. + The type 'readonly [1, "1"]' is 'readonly' and cannot be assigned to the mutable type '[a: 1 | 2, b: "1" | "2"]'. + + +==== tests/cases/compiler/contextualTupleTypeParameterReadonly.ts (1 errors) ==== + declare function each>(cases: ReadonlyArray): (fn: (...args: T) => any) => void; + + const cases = [ + [1, '1'], + [2, '2'], + ] as const; + + const eacher = each(cases); + + eacher((a, b) => { + ~~~~~~~~~~~ +!!! error TS2345: Argument of type '(a: 1 | 2, b: "1" | "2") => void' is not assignable to parameter of type '(...args: readonly [1, "1"] | readonly [2, "2"]) => any'. +!!! error TS2345: Types of parameters 'a' and 'args' are incompatible. +!!! error TS2345: Type 'readonly [1, "1"] | readonly [2, "2"]' is not assignable to type '[a: 1 | 2, b: "1" | "2"]'. +!!! error TS2345: The type 'readonly [1, "1"]' is 'readonly' and cannot be assigned to the mutable type '[a: 1 | 2, b: "1" | "2"]'. + a; + b; + }); + + eacher((...args) => { + const [a, b] = args; + a; + b; + }); + \ No newline at end of file diff --git a/tests/baselines/reference/contextualTupleTypeParameterReadonly.js b/tests/baselines/reference/contextualTupleTypeParameterReadonly.js new file mode 100644 index 0000000000000..ce65ec919ea70 --- /dev/null +++ b/tests/baselines/reference/contextualTupleTypeParameterReadonly.js @@ -0,0 +1,42 @@ +//// [contextualTupleTypeParameterReadonly.ts] +declare function each>(cases: ReadonlyArray): (fn: (...args: T) => any) => void; + +const cases = [ + [1, '1'], + [2, '2'], +] as const; + +const eacher = each(cases); + +eacher((a, b) => { + a; + b; +}); + +eacher((...args) => { + const [a, b] = args; + a; + b; +}); + + +//// [contextualTupleTypeParameterReadonly.js] +"use strict"; +var cases = [ + [1, '1'], + [2, '2'], +]; +var eacher = each(cases); +eacher(function (a, b) { + a; + b; +}); +eacher(function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + var a = args[0], b = args[1]; + a; + b; +}); diff --git a/tests/baselines/reference/contextualTupleTypeParameterReadonly.symbols b/tests/baselines/reference/contextualTupleTypeParameterReadonly.symbols new file mode 100644 index 0000000000000..25f165b697b81 --- /dev/null +++ b/tests/baselines/reference/contextualTupleTypeParameterReadonly.symbols @@ -0,0 +1,55 @@ +=== tests/cases/compiler/contextualTupleTypeParameterReadonly.ts === +declare function each>(cases: ReadonlyArray): (fn: (...args: T) => any) => void; +>each : Symbol(each, Decl(contextualTupleTypeParameterReadonly.ts, 0, 0)) +>T : Symbol(T, Decl(contextualTupleTypeParameterReadonly.ts, 0, 22)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) +>cases : Symbol(cases, Decl(contextualTupleTypeParameterReadonly.ts, 0, 52)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(contextualTupleTypeParameterReadonly.ts, 0, 22)) +>fn : Symbol(fn, Decl(contextualTupleTypeParameterReadonly.ts, 0, 79)) +>args : Symbol(args, Decl(contextualTupleTypeParameterReadonly.ts, 0, 84)) +>T : Symbol(T, Decl(contextualTupleTypeParameterReadonly.ts, 0, 22)) + +const cases = [ +>cases : Symbol(cases, Decl(contextualTupleTypeParameterReadonly.ts, 2, 5)) + + [1, '1'], + [2, '2'], +] as const; +>const : Symbol(const) + +const eacher = each(cases); +>eacher : Symbol(eacher, Decl(contextualTupleTypeParameterReadonly.ts, 7, 5)) +>each : Symbol(each, Decl(contextualTupleTypeParameterReadonly.ts, 0, 0)) +>cases : Symbol(cases, Decl(contextualTupleTypeParameterReadonly.ts, 2, 5)) + +eacher((a, b) => { +>eacher : Symbol(eacher, Decl(contextualTupleTypeParameterReadonly.ts, 7, 5)) +>a : Symbol(a, Decl(contextualTupleTypeParameterReadonly.ts, 9, 8)) +>b : Symbol(b, Decl(contextualTupleTypeParameterReadonly.ts, 9, 10)) + + a; +>a : Symbol(a, Decl(contextualTupleTypeParameterReadonly.ts, 9, 8)) + + b; +>b : Symbol(b, Decl(contextualTupleTypeParameterReadonly.ts, 9, 10)) + +}); + +eacher((...args) => { +>eacher : Symbol(eacher, Decl(contextualTupleTypeParameterReadonly.ts, 7, 5)) +>args : Symbol(args, Decl(contextualTupleTypeParameterReadonly.ts, 14, 8)) + + const [a, b] = args; +>a : Symbol(a, Decl(contextualTupleTypeParameterReadonly.ts, 15, 11)) +>b : Symbol(b, Decl(contextualTupleTypeParameterReadonly.ts, 15, 13)) +>args : Symbol(args, Decl(contextualTupleTypeParameterReadonly.ts, 14, 8)) + + a; +>a : Symbol(a, Decl(contextualTupleTypeParameterReadonly.ts, 15, 11)) + + b; +>b : Symbol(b, Decl(contextualTupleTypeParameterReadonly.ts, 15, 13)) + +}); + diff --git a/tests/baselines/reference/contextualTupleTypeParameterReadonly.types b/tests/baselines/reference/contextualTupleTypeParameterReadonly.types new file mode 100644 index 0000000000000..24b84ee2cc3a3 --- /dev/null +++ b/tests/baselines/reference/contextualTupleTypeParameterReadonly.types @@ -0,0 +1,64 @@ +=== tests/cases/compiler/contextualTupleTypeParameterReadonly.ts === +declare function each>(cases: ReadonlyArray): (fn: (...args: T) => any) => void; +>each : (cases: ReadonlyArray) => (fn: (...args: T) => any) => void +>cases : readonly T[] +>fn : (...args: T) => any +>args : T + +const cases = [ +>cases : readonly [readonly [1, "1"], readonly [2, "2"]] +>[ [1, '1'], [2, '2'],] as const : readonly [readonly [1, "1"], readonly [2, "2"]] +>[ [1, '1'], [2, '2'],] : readonly [readonly [1, "1"], readonly [2, "2"]] + + [1, '1'], +>[1, '1'] : readonly [1, "1"] +>1 : 1 +>'1' : "1" + + [2, '2'], +>[2, '2'] : readonly [2, "2"] +>2 : 2 +>'2' : "2" + +] as const; + +const eacher = each(cases); +>eacher : (fn: (...args: readonly [1, "1"] | readonly [2, "2"]) => any) => void +>each(cases) : (fn: (...args: readonly [1, "1"] | readonly [2, "2"]) => any) => void +>each : (cases: readonly T[]) => (fn: (...args: T) => any) => void +>cases : readonly [readonly [1, "1"], readonly [2, "2"]] + +eacher((a, b) => { +>eacher((a, b) => { a; b;}) : void +>eacher : (fn: (...args: readonly [1, "1"] | readonly [2, "2"]) => any) => void +>(a, b) => { a; b;} : (a: 1 | 2, b: "1" | "2") => void +>a : 1 | 2 +>b : "1" | "2" + + a; +>a : 1 | 2 + + b; +>b : "1" | "2" + +}); + +eacher((...args) => { +>eacher((...args) => { const [a, b] = args; a; b;}) : void +>eacher : (fn: (...args: readonly [1, "1"] | readonly [2, "2"]) => any) => void +>(...args) => { const [a, b] = args; a; b;} : (...args: readonly [1, "1"] | readonly [2, "2"]) => void +>args : readonly [1, "1"] | readonly [2, "2"] + + const [a, b] = args; +>a : 1 | 2 +>b : "1" | "2" +>args : readonly [1, "1"] | readonly [2, "2"] + + a; +>a : 1 | 2 + + b; +>b : "1" | "2" + +}); + diff --git a/tests/cases/compiler/contextualTupleTypeParameterReadonly.ts b/tests/cases/compiler/contextualTupleTypeParameterReadonly.ts new file mode 100644 index 0000000000000..1660832b37fd6 --- /dev/null +++ b/tests/cases/compiler/contextualTupleTypeParameterReadonly.ts @@ -0,0 +1,21 @@ +// @strict: true + +declare function each>(cases: ReadonlyArray): (fn: (...args: T) => any) => void; + +const cases = [ + [1, '1'], + [2, '2'], +] as const; + +const eacher = each(cases); + +eacher((a, b) => { + a; + b; +}); + +eacher((...args) => { + const [a, b] = args; + a; + b; +}); From 5f7155d89215382cd1b277a1f904a0638195f682 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:16:07 -0700 Subject: [PATCH 2/2] Ensure rest type for source parameter is readonly --- src/compiler/checker.ts | 8 ++--- ...xtualTupleTypeParameterReadonly.errors.txt | 32 ------------------- .../genericRestParameters3.errors.txt | 20 ++++++------ .../restTuplesFromContextualTypes.errors.txt | 8 ++--- 4 files changed, 18 insertions(+), 50 deletions(-) delete mode 100644 tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2515d81a58f7e..12c0ad40f4b4c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19810,7 +19810,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const restIndex = sourceRestType || targetRestType ? paramCount - 1 : -1; for (let i = 0; i < paramCount; i++) { - const sourceType = i === restIndex ? getRestTypeAtPosition(source, i) : tryGetTypeAtPosition(source, i); + const sourceType = i === restIndex ? getRestTypeAtPosition(source, i, /*readonly*/ true) : tryGetTypeAtPosition(source, i); const targetType = i === restIndex ? getRestTypeAtPosition(target, i) : tryGetTypeAtPosition(target, i); if (sourceType && targetType) { // In order to ensure that any generic type Foo is at least co-variant with respect to T no matter @@ -34565,12 +34565,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefined; } - function getRestTypeAtPosition(source: Signature, pos: number): Type { + function getRestTypeAtPosition(source: Signature, pos: number, readonly = false): Type { const parameterCount = getParameterCount(source); const minArgumentCount = getMinArgumentCount(source); const restType = getEffectiveRestType(source); if (restType && pos >= parameterCount - 1) { - return pos === parameterCount - 1 ? restType : createArrayType(getIndexedAccessType(restType, numberType)); + return pos === parameterCount - 1 ? restType : createArrayType(getIndexedAccessType(restType, numberType), readonly); } const types = []; const flags = []; @@ -34589,7 +34589,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { names.push(name); } } - return createTupleType(types, flags, /*readonly*/ false, length(names) === length(types) ? names : undefined); + return createTupleType(types, flags, readonly, length(names) === length(types) ? names : undefined); } // Return the number of parameters in a signature. The rest parameter, if present, counts as one diff --git a/tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt b/tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt deleted file mode 100644 index 2f68bc6125d1e..0000000000000 --- a/tests/baselines/reference/contextualTupleTypeParameterReadonly.errors.txt +++ /dev/null @@ -1,32 +0,0 @@ -tests/cases/compiler/contextualTupleTypeParameterReadonly.ts(10,8): error TS2345: Argument of type '(a: 1 | 2, b: "1" | "2") => void' is not assignable to parameter of type '(...args: readonly [1, "1"] | readonly [2, "2"]) => any'. - Types of parameters 'a' and 'args' are incompatible. - Type 'readonly [1, "1"] | readonly [2, "2"]' is not assignable to type '[a: 1 | 2, b: "1" | "2"]'. - The type 'readonly [1, "1"]' is 'readonly' and cannot be assigned to the mutable type '[a: 1 | 2, b: "1" | "2"]'. - - -==== tests/cases/compiler/contextualTupleTypeParameterReadonly.ts (1 errors) ==== - declare function each>(cases: ReadonlyArray): (fn: (...args: T) => any) => void; - - const cases = [ - [1, '1'], - [2, '2'], - ] as const; - - const eacher = each(cases); - - eacher((a, b) => { - ~~~~~~~~~~~ -!!! error TS2345: Argument of type '(a: 1 | 2, b: "1" | "2") => void' is not assignable to parameter of type '(...args: readonly [1, "1"] | readonly [2, "2"]) => any'. -!!! error TS2345: Types of parameters 'a' and 'args' are incompatible. -!!! error TS2345: Type 'readonly [1, "1"] | readonly [2, "2"]' is not assignable to type '[a: 1 | 2, b: "1" | "2"]'. -!!! error TS2345: The type 'readonly [1, "1"]' is 'readonly' and cannot be assigned to the mutable type '[a: 1 | 2, b: "1" | "2"]'. - a; - b; - }); - - eacher((...args) => { - const [a, b] = args; - a; - b; - }); - \ No newline at end of file diff --git a/tests/baselines/reference/genericRestParameters3.errors.txt b/tests/baselines/reference/genericRestParameters3.errors.txt index d306bbf3a6748..c2e350acf8115 100644 --- a/tests/baselines/reference/genericRestParameters3.errors.txt +++ b/tests/baselines/reference/genericRestParameters3.errors.txt @@ -6,19 +6,19 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(18,1): error TS2345 Source has 0 element(s) but target requires 2. tests/cases/conformance/types/rest/genericRestParameters3.ts(23,1): error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. Types of parameters 'y' and 'args' are incompatible. - Type '[string] | [number, boolean]' is not assignable to type '[y: string]'. - Type '[number, boolean]' is not assignable to type '[y: string]'. + Type '[string] | [number, boolean]' is not assignable to type 'readonly [y: string]'. + Type '[number, boolean]' is not assignable to type 'readonly [y: string]'. Source has 2 element(s) but target allows only 1. tests/cases/conformance/types/rest/genericRestParameters3.ts(24,1): error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. Types of parameters 'y' and 'args' are incompatible. - Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'. - Type '[string]' is not assignable to type '[y: number, z: boolean]'. + Type '[string] | [number, boolean]' is not assignable to type 'readonly [y: number, z: boolean]'. + Type '[string]' is not assignable to type 'readonly [y: number, z: boolean]'. Source has 1 element(s) but target requires 2. tests/cases/conformance/types/rest/genericRestParameters3.ts(35,1): error TS2554: Expected 1 arguments, but got 0. tests/cases/conformance/types/rest/genericRestParameters3.ts(36,21): error TS2345: Argument of type 'number' is not assignable to parameter of type '(...args: CoolArray) => void'. tests/cases/conformance/types/rest/genericRestParameters3.ts(37,21): error TS2345: Argument of type '(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray) => void'. Types of parameters 'cb' and 'args' are incompatible. - Property '0' is missing in type 'CoolArray' but required in type '[cb: (...args: any[]) => void]'. + Property '0' is missing in type 'CoolArray' but required in type 'readonly [cb: (...args: any[]) => void]'. tests/cases/conformance/types/rest/genericRestParameters3.ts(44,32): error TS2345: Argument of type '[10, 20]' is not assignable to parameter of type 'CoolArray'. Property 'hello' is missing in type '[10, 20]' but required in type 'CoolArray'. tests/cases/conformance/types/rest/genericRestParameters3.ts(49,1): error TS2345: Argument of type '[]' is not assignable to parameter of type 'CoolArray'. @@ -69,15 +69,15 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 ~~ !!! error TS2322: Type '(x: string, y: string) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. !!! error TS2322: Types of parameters 'y' and 'args' are incompatible. -!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[y: string]'. -!!! error TS2322: Type '[number, boolean]' is not assignable to type '[y: string]'. +!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type 'readonly [y: string]'. +!!! error TS2322: Type '[number, boolean]' is not assignable to type 'readonly [y: string]'. !!! error TS2322: Source has 2 element(s) but target allows only 1. f1 = f3; // Error ~~ !!! error TS2322: Type '(x: string, y: number, z: boolean) => void' is not assignable to type '(x: string, ...args: [string] | [number, boolean]) => void'. !!! error TS2322: Types of parameters 'y' and 'args' are incompatible. -!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type '[y: number, z: boolean]'. -!!! error TS2322: Type '[string]' is not assignable to type '[y: number, z: boolean]'. +!!! error TS2322: Type '[string] | [number, boolean]' is not assignable to type 'readonly [y: number, z: boolean]'. +!!! error TS2322: Type '[string]' is not assignable to type 'readonly [y: number, z: boolean]'. !!! error TS2322: Source has 1 element(s) but target requires 2. f1 = f4; @@ -100,7 +100,7 @@ tests/cases/conformance/types/rest/genericRestParameters3.ts(59,5): error TS2345 ~~~ !!! error TS2345: Argument of type '(cb: (...args: T) => void) => void' is not assignable to parameter of type '(...args: CoolArray) => void'. !!! error TS2345: Types of parameters 'cb' and 'args' are incompatible. -!!! error TS2345: Property '0' is missing in type 'CoolArray' but required in type '[cb: (...args: any[]) => void]'. +!!! error TS2345: Property '0' is missing in type 'CoolArray' but required in type 'readonly [cb: (...args: any[]) => void]'. function bar(...args: T): T { return args; diff --git a/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt b/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt index e182b72f57cdd..31d69f7f07651 100644 --- a/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt +++ b/tests/baselines/reference/restTuplesFromContextualTypes.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error TS2345: Argument of type '(a: number, b: T[0], ...x: T[number][]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'. Types of parameters 'b' and 'args' are incompatible. - Type 'T' is not assignable to type '[b: T[0], ...x: T[number][]]'. - Type 'any[]' is not assignable to type '[b: T[0], ...x: T[number][]]'. + Type 'T' is not assignable to type 'readonly [b: T[0], ...x: T[number][]]'. + Type 'any[]' is not assignable to type 'readonly [b: T[0], ...x: T[number][]]'. Source provides no match for required element at position 0 in target. @@ -65,8 +65,8 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error ~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '(a: number, b: T[0], ...x: T[number][]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'. !!! error TS2345: Types of parameters 'b' and 'args' are incompatible. -!!! error TS2345: Type 'T' is not assignable to type '[b: T[0], ...x: T[number][]]'. -!!! error TS2345: Type 'any[]' is not assignable to type '[b: T[0], ...x: T[number][]]'. +!!! error TS2345: Type 'T' is not assignable to type 'readonly [b: T[0], ...x: T[number][]]'. +!!! error TS2345: Type 'any[]' is not assignable to type 'readonly [b: T[0], ...x: T[number][]]'. !!! error TS2345: Source provides no match for required element at position 0 in target. }