diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7becc4a2f78c6..428d86606d178 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12246,6 +12246,40 @@ namespace ts { } } + /** + * Try and elaborate array and tuple errors. Returns false + * if we have found an elaboration, or we should ignore + * any other elaborations when relating the `source` and + * `target` types. + * + * @param source + * @param target + * @param reportErrors + */ + function tryElaborateArrayLikeErrors(source: Type, target: Type, reportErrors: boolean): boolean { + if (isTupleLikeType(source)) { + const sourceTuple: TupleType | undefined = (source as TupleTypeReference).target; + if (sourceTuple && sourceTuple.readonly && isArrayOrTupleLikeType(target) && + (!isReadonlyArrayType(target) || isTupleType(target) && !target.target.readonly)) { + if (reportErrors) { + reportError(Diagnostics.A_readonly_tuple_cannot_be_assigned_to_a_mutable_array_like_type); + } + return false; + } + return isArrayLikeType(target); + } + if (isTupleLikeType(target)) { + return isArrayLikeType(source); + } + if (isReadonlyArrayType(source) && isArrayType(target) && !isReadonlyArrayType(target)) { + if (reportErrors) { + reportError(Diagnostics.A_ReadonlyArray_cannot_be_assigned_to_an_Array_because_Array_s_can_be_mutated); + } + return false; + } + return true; + } + function isUnionOrIntersectionTypeWithoutNullableConstituents(type: Type): boolean { if (!(type.flags & TypeFlags.UnionOrIntersection)) { return false; @@ -12418,6 +12452,9 @@ namespace ts { if (!result && reportErrors) { const maybeSuppress = suppressNextError; suppressNextError = false; + if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) { + tryElaborateArrayLikeErrors(source, target, reportErrors); + } if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Primitive) { tryElaborateErrorsForPrimitivesAndObjects(source, target); } @@ -13148,11 +13185,13 @@ namespace ts { associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName)); } } - else if (props.length > 5) { // arbitrary cutoff for too-long list form - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); - } - else { - reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); + else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) { + if (props.length > 5) { // arbitrary cutoff for too-long list form + reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4); + } + else { + reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", ")); + } } } return Ternary.False; diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7717f51bd50fe..88bc5ffc3b95f 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2943,7 +2943,15 @@ "category": "Error", "code": 4103 }, - + "A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated.": { + "category": "Error", + "code": 4104 + }, + "A 'readonly' tuple cannot be assigned to a mutable array-like type.": { + "category": "Error", + "code": 4105 + }, + "The current host does not support the '{0}' option.": { "category": "Error", "code": 5001 diff --git a/tests/baselines/reference/iterableArrayPattern10.errors.txt b/tests/baselines/reference/iterableArrayPattern10.errors.txt index 9ec39f0ef955c..59b2079975da3 100644 --- a/tests/baselines/reference/iterableArrayPattern10.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern10.errors.txt @@ -1,5 +1,4 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts(17,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, any]'. - Type 'FooIterator' is missing the following properties from type '[any, any]': 0, 1, length, pop, and 26 more. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts (1 errors) ==== @@ -21,5 +20,4 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern10.ts(17,5): error function fun([a, b]) { } fun(new FooIterator); ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, any]'. -!!! error TS2345: Type 'FooIterator' is missing the following properties from type '[any, any]': 0, 1, length, pop, and 26 more. \ No newline at end of file +!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, any]'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern13.errors.txt b/tests/baselines/reference/iterableArrayPattern13.errors.txt index 780efa0de7fd4..af5452de5fa82 100644 --- a/tests/baselines/reference/iterableArrayPattern13.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern13.errors.txt @@ -1,5 +1,4 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts(17,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, ...any[]]'. - Type 'FooIterator' is missing the following properties from type '[any, ...any[]]': 0, length, pop, push, and 25 more. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts (1 errors) ==== @@ -21,5 +20,4 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern13.ts(17,5): error function fun([a, ...b]) { } fun(new FooIterator); ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, ...any[]]'. -!!! error TS2345: Type 'FooIterator' is missing the following properties from type '[any, ...any[]]': 0, length, pop, push, and 25 more. \ No newline at end of file +!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[any, ...any[]]'. \ No newline at end of file diff --git a/tests/baselines/reference/iterableArrayPattern16.errors.txt b/tests/baselines/reference/iterableArrayPattern16.errors.txt index 13b3981a94d90..9d01131954a10 100644 --- a/tests/baselines/reference/iterableArrayPattern16.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern16.errors.txt @@ -1,5 +1,4 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'. - Type 'FooIterator' is missing the following properties from type '[Bar, Bar]': 0, 1, length, pop, and 26 more. tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,12): error TS2449: Class 'FooIteratorIterator' used before its declaration. @@ -8,7 +7,6 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,12): error fun(...new FooIteratorIterator); ~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'. -!!! error TS2345: Type 'FooIterator' is missing the following properties from type '[Bar, Bar]': 0, 1, length, pop, and 26 more. ~~~~~~~~~~~~~~~~~~~ !!! error TS2449: Class 'FooIteratorIterator' used before its declaration. !!! related TS2728 tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts:18:7: 'FooIteratorIterator' is declared here. diff --git a/tests/baselines/reference/iterableArrayPattern26.errors.txt b/tests/baselines/reference/iterableArrayPattern26.errors.txt index f56f56e4504c5..820e5ead3a4d9 100644 --- a/tests/baselines/reference/iterableArrayPattern26.errors.txt +++ b/tests/baselines/reference/iterableArrayPattern26.errors.txt @@ -1,10 +1,8 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts(2,21): error TS2345: Argument of type 'Map' is not assignable to parameter of type '[string, number]'. - Type 'Map' is missing the following properties from type '[string, number]': 0, 1, length, pop, and 22 more. ==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts (1 errors) ==== function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { } takeFirstTwoEntries(new Map([["", 0], ["hello", 1]])); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type 'Map' is not assignable to parameter of type '[string, number]'. -!!! error TS2345: Type 'Map' is missing the following properties from type '[string, number]': 0, 1, length, pop, and 22 more. \ No newline at end of file +!!! error TS2345: Argument of type 'Map' is not assignable to parameter of type '[string, number]'. \ No newline at end of file diff --git a/tests/baselines/reference/readonlyArraysAndTuples.errors.txt b/tests/baselines/reference/readonlyArraysAndTuples.errors.txt index d2f051b6d815b..352db8dd220bc 100644 --- a/tests/baselines/reference/readonlyArraysAndTuples.errors.txt +++ b/tests/baselines/reference/readonlyArraysAndTuples.errors.txt @@ -2,11 +2,11 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(9,12): error TS13 tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(10,15): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(11,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(12,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple literal types. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(15,5): error TS2740: Type 'readonly string[]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(17,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(15,5): error TS4104: A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(17,5): error TS4105: A 'readonly' tuple cannot be assigned to a mutable array-like type. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(21,5): error TS2739: Type 'string[]' is missing the following properties from type '[string, string]': 0, 1 tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(22,5): error TS2740: Type 'readonly string[]' is missing the following properties from type '[string, string]': 0, 1, pop, push, and 5 more. -tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(23,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type '[string, string]': pop, push, reverse, shift, and 3 more. +tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(23,5): error TS4105: A 'readonly' tuple cannot be assigned to a mutable array-like type. tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 @@ -36,11 +36,11 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS27 function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) { ma = ra; // Error ~~ -!!! error TS2740: Type 'readonly string[]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. +!!! error TS4104: A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. ma = mt; ma = rt; // Error ~~ -!!! error TS2740: Type 'readonly [string, string]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more. +!!! error TS4105: A 'readonly' tuple cannot be assigned to a mutable array-like type. ra = ma; ra = mt; ra = rt; @@ -52,7 +52,7 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS27 !!! error TS2740: Type 'readonly string[]' is missing the following properties from type '[string, string]': 0, 1, pop, push, and 5 more. mt = rt; // Error ~~ -!!! error TS2740: Type 'readonly [string, string]' is missing the following properties from type '[string, string]': pop, push, reverse, shift, and 3 more. +!!! error TS4105: A 'readonly' tuple cannot be assigned to a mutable array-like type. rt = ma; // Error ~~ !!! error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1 diff --git a/tests/baselines/reference/readonlyTupleAndArrayElaboration.errors.txt b/tests/baselines/reference/readonlyTupleAndArrayElaboration.errors.txt new file mode 100644 index 0000000000000..b6512ba8620f5 --- /dev/null +++ b/tests/baselines/reference/readonlyTupleAndArrayElaboration.errors.txt @@ -0,0 +1,58 @@ +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(10,20): error TS2345: Argument of type 'readonly [3, 4]' is not assignable to parameter of type '[number, number]'. + A 'readonly' tuple cannot be assigned to a mutable array-like type. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(13,8): error TS2345: Argument of type 'readonly [3, 4]' is not assignable to parameter of type 'number[]'. + A 'readonly' tuple cannot be assigned to a mutable array-like type. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(16,9): error TS2345: Argument of type 'readonly [3, 4]' is not assignable to parameter of type 'number[]'. + A 'readonly' tuple cannot be assigned to a mutable array-like type. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(22,9): error TS2345: Argument of type 'readonly number[]' is not assignable to parameter of type 'number[]'. + A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(23,9): error TS2345: Argument of type 'readonly number[]' is not assignable to parameter of type 'number[]'. + A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. +tests/cases/compiler/readonlyTupleAndArrayElaboration.ts(24,9): error TS2345: Argument of type 'readonly number[]' is not assignable to parameter of type 'number[]'. + A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. + + +==== tests/cases/compiler/readonlyTupleAndArrayElaboration.ts (6 errors) ==== + // @strict + // #Repro from #30839 + + let point = [3, 4] as const; + + function distanceFromOrigin([x, y]: [number, number]) { + return Math.sqrt(x ** 2 + y ** 2); + } + + distanceFromOrigin(point); + ~~~~~ +!!! error TS2345: Argument of type 'readonly [3, 4]' is not assignable to parameter of type '[number, number]'. +!!! error TS2345: A 'readonly' tuple cannot be assigned to a mutable array-like type. + + declare function arryFn(x: number[]): void; + arryFn(point); + ~~~~~ +!!! error TS2345: Argument of type 'readonly [3, 4]' is not assignable to parameter of type 'number[]'. +!!! error TS2345: A 'readonly' tuple cannot be assigned to a mutable array-like type. + + declare function arryFn2(x: Array): void; + arryFn2(point); + ~~~~~ +!!! error TS2345: Argument of type 'readonly [3, 4]' is not assignable to parameter of type 'number[]'. +!!! error TS2345: A 'readonly' tuple cannot be assigned to a mutable array-like type. + + declare const a: readonly number[]; + declare const b: Readonly; + declare const c: ReadonlyArray; + + arryFn2(a); + ~ +!!! error TS2345: Argument of type 'readonly number[]' is not assignable to parameter of type 'number[]'. +!!! error TS2345: A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. + arryFn2(b); + ~ +!!! error TS2345: Argument of type 'readonly number[]' is not assignable to parameter of type 'number[]'. +!!! error TS2345: A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. + arryFn2(c); + ~ +!!! error TS2345: Argument of type 'readonly number[]' is not assignable to parameter of type 'number[]'. +!!! error TS2345: A 'ReadonlyArray' cannot be assigned to an 'Array' because 'Array's can be mutated. + \ No newline at end of file diff --git a/tests/baselines/reference/readonlyTupleAndArrayElaboration.js b/tests/baselines/reference/readonlyTupleAndArrayElaboration.js new file mode 100644 index 0000000000000..7687dc176fd2f --- /dev/null +++ b/tests/baselines/reference/readonlyTupleAndArrayElaboration.js @@ -0,0 +1,41 @@ +//// [readonlyTupleAndArrayElaboration.ts] +// @strict +// #Repro from #30839 + +let point = [3, 4] as const; + +function distanceFromOrigin([x, y]: [number, number]) { + return Math.sqrt(x ** 2 + y ** 2); +} + +distanceFromOrigin(point); + +declare function arryFn(x: number[]): void; +arryFn(point); + +declare function arryFn2(x: Array): void; +arryFn2(point); + +declare const a: readonly number[]; +declare const b: Readonly; +declare const c: ReadonlyArray; + +arryFn2(a); +arryFn2(b); +arryFn2(c); + + +//// [readonlyTupleAndArrayElaboration.js] +// @strict +// #Repro from #30839 +var point = [3, 4]; +function distanceFromOrigin(_a) { + var x = _a[0], y = _a[1]; + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); +} +distanceFromOrigin(point); +arryFn(point); +arryFn2(point); +arryFn2(a); +arryFn2(b); +arryFn2(c); diff --git a/tests/baselines/reference/readonlyTupleAndArrayElaboration.symbols b/tests/baselines/reference/readonlyTupleAndArrayElaboration.symbols new file mode 100644 index 0000000000000..bbda544f3c729 --- /dev/null +++ b/tests/baselines/reference/readonlyTupleAndArrayElaboration.symbols @@ -0,0 +1,64 @@ +=== tests/cases/compiler/readonlyTupleAndArrayElaboration.ts === +// @strict +// #Repro from #30839 + +let point = [3, 4] as const; +>point : Symbol(point, Decl(readonlyTupleAndArrayElaboration.ts, 3, 3)) + +function distanceFromOrigin([x, y]: [number, number]) { +>distanceFromOrigin : Symbol(distanceFromOrigin, Decl(readonlyTupleAndArrayElaboration.ts, 3, 28)) +>x : Symbol(x, Decl(readonlyTupleAndArrayElaboration.ts, 5, 29)) +>y : Symbol(y, Decl(readonlyTupleAndArrayElaboration.ts, 5, 31)) + + return Math.sqrt(x ** 2 + y ** 2); +>Math.sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --)) +>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>sqrt : Symbol(Math.sqrt, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(readonlyTupleAndArrayElaboration.ts, 5, 29)) +>y : Symbol(y, Decl(readonlyTupleAndArrayElaboration.ts, 5, 31)) +} + +distanceFromOrigin(point); +>distanceFromOrigin : Symbol(distanceFromOrigin, Decl(readonlyTupleAndArrayElaboration.ts, 3, 28)) +>point : Symbol(point, Decl(readonlyTupleAndArrayElaboration.ts, 3, 3)) + +declare function arryFn(x: number[]): void; +>arryFn : Symbol(arryFn, Decl(readonlyTupleAndArrayElaboration.ts, 9, 26)) +>x : Symbol(x, Decl(readonlyTupleAndArrayElaboration.ts, 11, 24)) + +arryFn(point); +>arryFn : Symbol(arryFn, Decl(readonlyTupleAndArrayElaboration.ts, 9, 26)) +>point : Symbol(point, Decl(readonlyTupleAndArrayElaboration.ts, 3, 3)) + +declare function arryFn2(x: Array): void; +>arryFn2 : Symbol(arryFn2, Decl(readonlyTupleAndArrayElaboration.ts, 12, 14)) +>x : Symbol(x, Decl(readonlyTupleAndArrayElaboration.ts, 14, 25)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +arryFn2(point); +>arryFn2 : Symbol(arryFn2, Decl(readonlyTupleAndArrayElaboration.ts, 12, 14)) +>point : Symbol(point, Decl(readonlyTupleAndArrayElaboration.ts, 3, 3)) + +declare const a: readonly number[]; +>a : Symbol(a, Decl(readonlyTupleAndArrayElaboration.ts, 17, 13)) + +declare const b: Readonly; +>b : Symbol(b, Decl(readonlyTupleAndArrayElaboration.ts, 18, 13)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) + +declare const c: ReadonlyArray; +>c : Symbol(c, Decl(readonlyTupleAndArrayElaboration.ts, 19, 13)) +>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --)) + +arryFn2(a); +>arryFn2 : Symbol(arryFn2, Decl(readonlyTupleAndArrayElaboration.ts, 12, 14)) +>a : Symbol(a, Decl(readonlyTupleAndArrayElaboration.ts, 17, 13)) + +arryFn2(b); +>arryFn2 : Symbol(arryFn2, Decl(readonlyTupleAndArrayElaboration.ts, 12, 14)) +>b : Symbol(b, Decl(readonlyTupleAndArrayElaboration.ts, 18, 13)) + +arryFn2(c); +>arryFn2 : Symbol(arryFn2, Decl(readonlyTupleAndArrayElaboration.ts, 12, 14)) +>c : Symbol(c, Decl(readonlyTupleAndArrayElaboration.ts, 19, 13)) + diff --git a/tests/baselines/reference/readonlyTupleAndArrayElaboration.types b/tests/baselines/reference/readonlyTupleAndArrayElaboration.types new file mode 100644 index 0000000000000..8634cbc7229e2 --- /dev/null +++ b/tests/baselines/reference/readonlyTupleAndArrayElaboration.types @@ -0,0 +1,77 @@ +=== tests/cases/compiler/readonlyTupleAndArrayElaboration.ts === +// @strict +// #Repro from #30839 + +let point = [3, 4] as const; +>point : readonly [3, 4] +>[3, 4] as const : readonly [3, 4] +>[3, 4] : readonly [3, 4] +>3 : 3 +>4 : 4 + +function distanceFromOrigin([x, y]: [number, number]) { +>distanceFromOrigin : ([x, y]: [number, number]) => number +>x : number +>y : number + + return Math.sqrt(x ** 2 + y ** 2); +>Math.sqrt(x ** 2 + y ** 2) : number +>Math.sqrt : (x: number) => number +>Math : Math +>sqrt : (x: number) => number +>x ** 2 + y ** 2 : number +>x ** 2 : number +>x : number +>2 : 2 +>y ** 2 : number +>y : number +>2 : 2 +} + +distanceFromOrigin(point); +>distanceFromOrigin(point) : number +>distanceFromOrigin : ([x, y]: [number, number]) => number +>point : readonly [3, 4] + +declare function arryFn(x: number[]): void; +>arryFn : (x: number[]) => void +>x : number[] + +arryFn(point); +>arryFn(point) : void +>arryFn : (x: number[]) => void +>point : readonly [3, 4] + +declare function arryFn2(x: Array): void; +>arryFn2 : (x: number[]) => void +>x : number[] + +arryFn2(point); +>arryFn2(point) : void +>arryFn2 : (x: number[]) => void +>point : readonly [3, 4] + +declare const a: readonly number[]; +>a : readonly number[] + +declare const b: Readonly; +>b : readonly number[] + +declare const c: ReadonlyArray; +>c : readonly number[] + +arryFn2(a); +>arryFn2(a) : void +>arryFn2 : (x: number[]) => void +>a : readonly number[] + +arryFn2(b); +>arryFn2(b) : void +>arryFn2 : (x: number[]) => void +>b : readonly number[] + +arryFn2(c); +>arryFn2(c) : void +>arryFn2 : (x: number[]) => void +>c : readonly number[] + diff --git a/tests/cases/compiler/readonlyTupleAndArrayElaboration.ts b/tests/cases/compiler/readonlyTupleAndArrayElaboration.ts new file mode 100644 index 0000000000000..9f52d8832ae07 --- /dev/null +++ b/tests/cases/compiler/readonlyTupleAndArrayElaboration.ts @@ -0,0 +1,24 @@ +// @strict +// #Repro from #30839 + +let point = [3, 4] as const; + +function distanceFromOrigin([x, y]: [number, number]) { + return Math.sqrt(x ** 2 + y ** 2); +} + +distanceFromOrigin(point); + +declare function arryFn(x: number[]): void; +arryFn(point); + +declare function arryFn2(x: Array): void; +arryFn2(point); + +declare const a: readonly number[]; +declare const b: Readonly; +declare const c: ReadonlyArray; + +arryFn2(a); +arryFn2(b); +arryFn2(c);