Accepted baselines.

This commit is contained in:
Daniel Rosenwasser
2023-01-19 23:40:03 +00:00
parent 4d51879631
commit 241b3f2fe2
11 changed files with 94 additions and 75 deletions
@@ -2,20 +2,20 @@
// Repro from #17711
Object.freeze({
>Object.freeze({ foo() { return Object.freeze('a'); },}) : Readonly<{ foo(): string; }>
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Object.freeze({ foo() { return Object.freeze('a'); },}) : Readonly<{ readonly foo: () => "a"; }>
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>{ foo() { return Object.freeze('a'); },} : { foo(): string; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>{ foo() { return Object.freeze('a'); },} : { foo(): "a"; }
foo() {
>foo : () => string
>foo : () => "a"
return Object.freeze('a');
>Object.freeze('a') : string
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Object.freeze('a') : "a"
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>'a' : "a"
},
@@ -1105,7 +1105,7 @@
"target": {
"fileName": "lib.d.ts",
"textSpan": {
"start": 18529,
"start": 18541,
"length": 28
}
}
@@ -1128,7 +1128,7 @@
"target": {
"fileName": "lib.d.ts",
"textSpan": {
"start": 18529,
"start": 18541,
"length": 28
}
}
@@ -2,10 +2,10 @@
// #49101
Object.freeze({
>Object.freeze({ f: function () { }}) : Readonly<{ f: () => void; }>
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Object.freeze({ f: function () { }}) : Readonly<{ readonly f: () => void; }>
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>{ f: function () { }} : { f: () => void; }
f: function () { }
@@ -1,6 +1,6 @@
=== tests/cases/compiler/usage.js ===
const { Thing, useThing, cbThing } = require("./index");
>Thing : Readonly<{ a: "thing"; b: "chill"; }>
>Thing : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
>useThing : (x: string) => void
>cbThing : (x: (x: string) => void) => void
>require("./index") : typeof import("tests/cases/compiler/index")
@@ -11,7 +11,7 @@ useThing(Thing.a);
>useThing(Thing.a) : void
>useThing : (x: string) => void
>Thing.a : "thing"
>Thing : Readonly<{ a: "thing"; b: "chill"; }>
>Thing : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
>a : "thing"
/**
@@ -47,11 +47,11 @@ cbThing(type => {
=== tests/cases/compiler/index.js ===
/** @enum {string} */
const Thing = Object.freeze({
>Thing : Readonly<{ a: "thing"; b: "chill"; }>
>Object.freeze({ a: "thing", b: "chill"}) : Readonly<{ a: "thing"; b: "chill"; }>
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Thing : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
>Object.freeze({ a: "thing", b: "chill"}) : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>{ a: "thing", b: "chill"} : { a: "thing"; b: "chill"; }
a: "thing",
@@ -65,11 +65,11 @@ const Thing = Object.freeze({
});
exports.Thing = Thing;
>exports.Thing = Thing : Readonly<{ a: "thing"; b: "chill"; }>
>exports.Thing : Readonly<{ a: "thing"; b: "chill"; }>
>exports.Thing = Thing : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
>exports.Thing : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
>exports : typeof import("tests/cases/compiler/index")
>Thing : Readonly<{ a: "thing"; b: "chill"; }>
>Thing : Readonly<{ a: "thing"; b: "chill"; }>
>Thing : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
>Thing : Readonly<{ readonly a: "thing"; readonly b: "chill"; }>
/**
* @param {Thing} x
@@ -1876,9 +1876,9 @@ class SampleClass<P> {
>this : this
>props : Readonly<P>
>Object.freeze(props) : Readonly<P>
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U | null | undefined; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>props : P
}
}
@@ -1,9 +1,8 @@
tests/cases/compiler/objectFreeze.ts(9,1): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/compiler/objectFreeze.ts(9,1): error TS2542: Index signature in type 'readonly number[]' only permits reading.
tests/cases/compiler/objectFreeze.ts(9,3): error TS2540: Cannot assign to '0' because it is a read-only property.
tests/cases/compiler/objectFreeze.ts(12,3): error TS2540: Cannot assign to 'b' because it is a read-only property.
==== tests/cases/compiler/objectFreeze.ts (3 errors) ====
==== tests/cases/compiler/objectFreeze.ts (2 errors) ====
const f = Object.freeze(function foo(a: number, b: string) { return false; });
f(1, "") === false;
@@ -13,10 +12,8 @@ tests/cases/compiler/objectFreeze.ts(12,3): error TS2540: Cannot assign to 'b' b
const a = Object.freeze([1, 2, 3]);
a[0] = a[2].toString();
~~~~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
~~~~
!!! error TS2542: Index signature in type 'readonly number[]' only permits reading.
~
!!! error TS2540: Cannot assign to '0' because it is a read-only property.
const o = Object.freeze({ a: 1, b: "string", c: true });
o.b = o.a.toString();
@@ -33,8 +33,10 @@ const a = Object.freeze([1, 2, 3]);
a[0] = a[2].toString();
>a : Symbol(a, Decl(objectFreeze.ts, 7, 5))
>0 : Symbol(0)
>a[2].toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(objectFreeze.ts, 7, 5))
>2 : Symbol(2)
>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
const o = Object.freeze({ a: 1, b: "string", c: true });
+19 -19
View File
@@ -2,9 +2,9 @@
const f = Object.freeze(function foo(a: number, b: string) { return false; });
>f : (a: number, b: string) => false
>Object.freeze(function foo(a: number, b: string) { return false; }) : (a: number, b: string) => false
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>function foo(a: number, b: string) { return false; } : (a: number, b: string) => false
>foo : (a: number, b: string) => false
>a : number
@@ -26,9 +26,9 @@ class C { constructor(a: number) { } }
const c = Object.freeze(C);
>c : typeof C
>Object.freeze(C) : typeof C
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>C : typeof C
new c(1);
@@ -37,34 +37,34 @@ new c(1);
>1 : 1
const a = Object.freeze([1, 2, 3]);
>a : readonly number[]
>Object.freeze([1, 2, 3]) : readonly number[]
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>a : readonly [1, 2, 3]
>Object.freeze([1, 2, 3]) : readonly [1, 2, 3]
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>[1, 2, 3] : number[]
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>[1, 2, 3] : [1, 2, 3]
>1 : 1
>2 : 2
>3 : 3
a[0] = a[2].toString();
>a[0] = a[2].toString() : string
>a[0] : number
>a : readonly number[]
>a[0] : any
>a : readonly [1, 2, 3]
>0 : 0
>a[2].toString() : string
>a[2].toString : (radix?: number) => string
>a[2] : number
>a : readonly number[]
>a[2] : 3
>a : readonly [1, 2, 3]
>2 : 2
>toString : (radix?: number) => string
const o = Object.freeze({ a: 1, b: "string", c: true });
>o : Readonly<{ a: 1; b: "string"; c: true; }>
>Object.freeze({ a: 1, b: "string", c: true }) : Readonly<{ a: 1; b: "string"; c: true; }>
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>o : Readonly<{ readonly a: 1; readonly b: "string"; readonly c: true; }>
>Object.freeze({ a: 1, b: "string", c: true }) : Readonly<{ readonly a: 1; readonly b: "string"; readonly c: true; }>
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>{ a: 1, b: "string", c: true } : { a: 1; b: "string"; c: true; }
>a : 1
>1 : 1
@@ -76,12 +76,12 @@ const o = Object.freeze({ a: 1, b: "string", c: true });
o.b = o.a.toString();
>o.b = o.a.toString() : string
>o.b : any
>o : Readonly<{ a: 1; b: "string"; c: true; }>
>o : Readonly<{ readonly a: 1; readonly b: "string"; readonly c: true; }>
>b : any
>o.a.toString() : string
>o.a.toString : (radix?: number) => string
>o.a : 1
>o : Readonly<{ a: 1; b: "string"; c: true; }>
>o : Readonly<{ readonly a: 1; readonly b: "string"; readonly c: true; }>
>a : 1
>toString : (radix?: number) => string
@@ -1,10 +1,10 @@
=== tests/cases/compiler/objectFreezeLiteralsDontWiden.ts ===
const PUPPETEER_REVISIONS = Object.freeze({
>PUPPETEER_REVISIONS : Readonly<{ chromium: "1011831"; firefox: "latest"; }>
>Object.freeze({ chromium: '1011831', firefox: 'latest',}) : Readonly<{ chromium: "1011831"; firefox: "latest"; }>
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>PUPPETEER_REVISIONS : Readonly<{ readonly chromium: "1011831"; readonly firefox: "latest"; }>
>Object.freeze({ chromium: '1011831', firefox: 'latest',}) : Readonly<{ readonly chromium: "1011831"; readonly firefox: "latest"; }>
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>{ chromium: '1011831', firefox: 'latest',} : { chromium: "1011831"; firefox: "latest"; }
chromium: '1011831',
@@ -20,13 +20,13 @@ const PUPPETEER_REVISIONS = Object.freeze({
let preferredRevision = PUPPETEER_REVISIONS.chromium;
>preferredRevision : "1011831"
>PUPPETEER_REVISIONS.chromium : "1011831"
>PUPPETEER_REVISIONS : Readonly<{ chromium: "1011831"; firefox: "latest"; }>
>PUPPETEER_REVISIONS : Readonly<{ readonly chromium: "1011831"; readonly firefox: "latest"; }>
>chromium : "1011831"
preferredRevision = PUPPETEER_REVISIONS.firefox;
>preferredRevision = PUPPETEER_REVISIONS.firefox : "latest"
>preferredRevision : "1011831"
>PUPPETEER_REVISIONS.firefox : "latest"
>PUPPETEER_REVISIONS : Readonly<{ chromium: "1011831"; firefox: "latest"; }>
>PUPPETEER_REVISIONS : Readonly<{ readonly chromium: "1011831"; readonly firefox: "latest"; }>
>firefox : "latest"
@@ -0,0 +1,20 @@
tests/cases/compiler/objectFromEntries.ts(8,7): error TS2322: Type 'readonly [readonly ["a", 1], readonly ["b", 2], readonly ["c", 3]]' is not assignable to type 'readonly [string, number][]'.
Type 'readonly ["a", 1] | readonly ["b", 2] | readonly ["c", 3]' is not assignable to type '[string, number]'.
The type 'readonly ["a", 1]' is 'readonly' and cannot be assigned to the mutable type '[string, number]'.
==== tests/cases/compiler/objectFromEntries.ts (1 errors) ====
const o = Object.fromEntries([['a', 1], ['b', 2], ['c', 3]]);
const o2 = Object.fromEntries(new URLSearchParams());
const o3 = Object.fromEntries(new Map([[Symbol("key"), "value"]]));
const frozenArray = Object.freeze([['a', 1], ['b', 2], ['c', 3]]);
const o4 = Object.fromEntries(frozenArray);
const frozenArray2: readonly [string, number][] = Object.freeze([['a', 1], ['b', 2], ['c', 3]]);
~~~~~~~~~~~~
!!! error TS2322: Type 'readonly [readonly ["a", 1], readonly ["b", 2], readonly ["c", 3]]' is not assignable to type 'readonly [string, number][]'.
!!! error TS2322: Type 'readonly ["a", 1] | readonly ["b", 2] | readonly ["c", 3]' is not assignable to type '[string, number]'.
!!! error TS2322: The type 'readonly ["a", 1]' is 'readonly' and cannot be assigned to the mutable type '[string, number]'.
const o5 = Object.fromEntries(frozenArray2);
@@ -41,44 +41,44 @@ const o3 = Object.fromEntries(new Map([[Symbol("key"), "value"]]));
>"value" : "value"
const frozenArray = Object.freeze([['a', 1], ['b', 2], ['c', 3]]);
>frozenArray : readonly (string | number)[][]
>Object.freeze([['a', 1], ['b', 2], ['c', 3]]) : readonly (string | number)[][]
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>frozenArray : readonly [readonly ["a", 1], readonly ["b", 2], readonly ["c", 3]]
>Object.freeze([['a', 1], ['b', 2], ['c', 3]]) : readonly [readonly ["a", 1], readonly ["b", 2], readonly ["c", 3]]
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>[['a', 1], ['b', 2], ['c', 3]] : (string | number)[][]
>['a', 1] : (string | number)[]
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>[['a', 1], ['b', 2], ['c', 3]] : [["a", 1], ["b", 2], ["c", 3]]
>['a', 1] : ["a", 1]
>'a' : "a"
>1 : 1
>['b', 2] : (string | number)[]
>['b', 2] : ["b", 2]
>'b' : "b"
>2 : 2
>['c', 3] : (string | number)[]
>['c', 3] : ["c", 3]
>'c' : "c"
>3 : 3
const o4 = Object.fromEntries(frozenArray);
>o4 : any
>Object.fromEntries(frozenArray) : any
>o4 : { [k: string]: 2 | 1 | 3; }
>Object.fromEntries(frozenArray) : { [k: string]: 2 | 1 | 3; }
>Object.fromEntries : { <T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T; }; (entries: Iterable<readonly any[]>): any; }
>Object : ObjectConstructor
>fromEntries : { <T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T; }; (entries: Iterable<readonly any[]>): any; }
>frozenArray : readonly (string | number)[][]
>frozenArray : readonly [readonly ["a", 1], readonly ["b", 2], readonly ["c", 3]]
const frozenArray2: readonly [string, number][] = Object.freeze([['a', 1], ['b', 2], ['c', 3]]);
>frozenArray2 : readonly [string, number][]
>Object.freeze([['a', 1], ['b', 2], ['c', 3]]) : readonly [string, number][]
>Object.freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>Object.freeze([['a', 1], ['b', 2], ['c', 3]]) : readonly [readonly ["a", 1], readonly ["b", 2], readonly ["c", 3]]
>Object.freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T extends Function>(f: T): T; <T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <T>(o: T): Readonly<T>; }
>[['a', 1], ['b', 2], ['c', 3]] : [string, number][]
>['a', 1] : [string, number]
>freeze : { <T extends Function>(f: T): T; <const T extends { [idx: string]: object | U; }, U extends string | number | bigint | boolean | symbol>(o: T): Readonly<T>; <const T>(o: T): Readonly<T>; }
>[['a', 1], ['b', 2], ['c', 3]] : [["a", 1], ["b", 2], ["c", 3]]
>['a', 1] : ["a", 1]
>'a' : "a"
>1 : 1
>['b', 2] : [string, number]
>['b', 2] : ["b", 2]
>'b' : "b"
>2 : 2
>['c', 3] : [string, number]
>['c', 3] : ["c", 3]
>'c' : "c"
>3 : 3