From e1fe677658c00de69e58af007c14ebb9589b54de Mon Sep 17 00:00:00 2001 From: Zzzen Date: Thu, 3 Feb 2022 21:19:02 +0800 Subject: [PATCH] mark length of readonly tuple as readonly --- src/compiler/checker.ts | 2 +- .../baselines/reference/tupleTypes.errors.txt | 26 ++++++++- tests/baselines/reference/tupleTypes.js | 17 ++++++ tests/baselines/reference/tupleTypes.symbols | 45 ++++++++++++++++ tests/baselines/reference/tupleTypes.types | 53 +++++++++++++++++++ tests/cases/compiler/tupleTypes.ts | 12 +++++ 6 files changed, 153 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cffd5acc4563a..97414e6853e3a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14036,7 +14036,7 @@ namespace ts { } } const fixedLength = properties.length; - const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String); + const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String, readonly ? CheckFlags.Readonly : 0); if (combinedFlags & ElementFlags.Variable) { lengthSymbol.type = numberType; } diff --git a/tests/baselines/reference/tupleTypes.errors.txt b/tests/baselines/reference/tupleTypes.errors.txt index c819aabf00523..581ee6e73f5d6 100644 --- a/tests/baselines/reference/tupleTypes.errors.txt +++ b/tests/baselines/reference/tupleTypes.errors.txt @@ -23,9 +23,13 @@ tests/cases/compiler/tupleTypes.ts(50,1): error TS2322: Type '[number, number]' tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is not assignable to type '[number, string]'. Type at position 1 in source is not compatible with type at position 1 in target. Type '{}' is not assignable to type 'string'. +tests/cases/compiler/tupleTypes.ts(57,1): error TS2322: Type '0' is not assignable to type '1'. +tests/cases/compiler/tupleTypes.ts(59,4): error TS2540: Cannot assign to 'length' because it is a read-only property. +tests/cases/compiler/tupleTypes.ts(61,4): error TS2540: Cannot assign to 'length' because it is a read-only property. +tests/cases/compiler/tupleTypes.ts(63,4): error TS2540: Cannot assign to 'length' because it is a read-only property. -==== tests/cases/compiler/tupleTypes.ts (14 errors) ==== +==== tests/cases/compiler/tupleTypes.ts (18 errors) ==== var v1: []; // Error var v2: [number]; var v3: [number, string]; @@ -120,4 +124,24 @@ tests/cases/compiler/tupleTypes.ts(51,1): error TS2322: Type '[number, {}]' is n !!! error TS2322: Type '{}' is not assignable to type 'string'. a3 = a1; a3 = a2; + + type B = Pick<[number], 'length'>; + declare const b: B; + b.length = 0; // Error + ~~~~~~~~ +!!! error TS2322: Type '0' is not assignable to type '1'. + declare const b1: readonly [number?]; + b1.length = 0; // Error + ~~~~~~ +!!! error TS2540: Cannot assign to 'length' because it is a read-only property. + declare const b2: readonly [number, ...number[]]; + b2.length = 0; // Error + ~~~~~~ +!!! error TS2540: Cannot assign to 'length' because it is a read-only property. + declare const b3: readonly number[]; + b3.length = 0; // Error + ~~~~~~ +!!! error TS2540: Cannot assign to 'length' because it is a read-only property. + declare const b4: [number?]; + b4.length = 0; \ No newline at end of file diff --git a/tests/baselines/reference/tupleTypes.js b/tests/baselines/reference/tupleTypes.js index 947b7bba30bc7..818c2f44e92de 100644 --- a/tests/baselines/reference/tupleTypes.js +++ b/tests/baselines/reference/tupleTypes.js @@ -52,6 +52,18 @@ a1 = a2; // Error a1 = a3; // Error a3 = a1; a3 = a2; + +type B = Pick<[number], 'length'>; +declare const b: B; +b.length = 0; // Error +declare const b1: readonly [number?]; +b1.length = 0; // Error +declare const b2: readonly [number, ...number[]]; +b2.length = 0; // Error +declare const b3: readonly number[]; +b3.length = 0; // Error +declare const b4: [number?]; +b4.length = 0; //// [tupleTypes.js] @@ -99,3 +111,8 @@ a1 = a2; // Error a1 = a3; // Error a3 = a1; a3 = a2; +b.length = 0; // Error +b1.length = 0; // Error +b2.length = 0; // Error +b3.length = 0; // Error +b4.length = 0; diff --git a/tests/baselines/reference/tupleTypes.symbols b/tests/baselines/reference/tupleTypes.symbols index a886271b6ee43..1d3f27877c385 100644 --- a/tests/baselines/reference/tupleTypes.symbols +++ b/tests/baselines/reference/tupleTypes.symbols @@ -184,3 +184,48 @@ a3 = a2; >a3 : Symbol(a3, Decl(tupleTypes.ts, 45, 3)) >a2 : Symbol(a2, Decl(tupleTypes.ts, 44, 3)) +type B = Pick<[number], 'length'>; +>B : Symbol(B, Decl(tupleTypes.ts, 52, 8)) +>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --)) + +declare const b: B; +>b : Symbol(b, Decl(tupleTypes.ts, 55, 13)) +>B : Symbol(B, Decl(tupleTypes.ts, 52, 8)) + +b.length = 0; // Error +>b.length : Symbol(length) +>b : Symbol(b, Decl(tupleTypes.ts, 55, 13)) +>length : Symbol(length) + +declare const b1: readonly [number?]; +>b1 : Symbol(b1, Decl(tupleTypes.ts, 57, 13)) + +b1.length = 0; // Error +>b1.length : Symbol(length) +>b1 : Symbol(b1, Decl(tupleTypes.ts, 57, 13)) +>length : Symbol(length) + +declare const b2: readonly [number, ...number[]]; +>b2 : Symbol(b2, Decl(tupleTypes.ts, 59, 13)) + +b2.length = 0; // Error +>b2.length : Symbol(length) +>b2 : Symbol(b2, Decl(tupleTypes.ts, 59, 13)) +>length : Symbol(length) + +declare const b3: readonly number[]; +>b3 : Symbol(b3, Decl(tupleTypes.ts, 61, 13)) + +b3.length = 0; // Error +>b3.length : Symbol(ReadonlyArray.length, Decl(lib.es5.d.ts, --, --)) +>b3 : Symbol(b3, Decl(tupleTypes.ts, 61, 13)) +>length : Symbol(ReadonlyArray.length, Decl(lib.es5.d.ts, --, --)) + +declare const b4: [number?]; +>b4 : Symbol(b4, Decl(tupleTypes.ts, 63, 13)) + +b4.length = 0; +>b4.length : Symbol(length) +>b4 : Symbol(b4, Decl(tupleTypes.ts, 63, 13)) +>length : Symbol(length) + diff --git a/tests/baselines/reference/tupleTypes.types b/tests/baselines/reference/tupleTypes.types index 12eaf588b98ec..a1b0a345f00f1 100644 --- a/tests/baselines/reference/tupleTypes.types +++ b/tests/baselines/reference/tupleTypes.types @@ -226,3 +226,56 @@ a3 = a2; >a3 : [number, {}] >a2 : [number, number] +type B = Pick<[number], 'length'>; +>B : B + +declare const b: B; +>b : B + +b.length = 0; // Error +>b.length = 0 : 0 +>b.length : 1 +>b : B +>length : 1 +>0 : 0 + +declare const b1: readonly [number?]; +>b1 : readonly [number?] + +b1.length = 0; // Error +>b1.length = 0 : 0 +>b1.length : any +>b1 : readonly [number?] +>length : any +>0 : 0 + +declare const b2: readonly [number, ...number[]]; +>b2 : readonly [number, ...number[]] + +b2.length = 0; // Error +>b2.length = 0 : 0 +>b2.length : any +>b2 : readonly [number, ...number[]] +>length : any +>0 : 0 + +declare const b3: readonly number[]; +>b3 : readonly number[] + +b3.length = 0; // Error +>b3.length = 0 : 0 +>b3.length : any +>b3 : readonly number[] +>length : any +>0 : 0 + +declare const b4: [number?]; +>b4 : [number?] + +b4.length = 0; +>b4.length = 0 : 0 +>b4.length : 0 | 1 +>b4 : [number?] +>length : 0 | 1 +>0 : 0 + diff --git a/tests/cases/compiler/tupleTypes.ts b/tests/cases/compiler/tupleTypes.ts index 53e5b584b7a9c..40bc1e9b27740 100644 --- a/tests/cases/compiler/tupleTypes.ts +++ b/tests/cases/compiler/tupleTypes.ts @@ -51,3 +51,15 @@ a1 = a2; // Error a1 = a3; // Error a3 = a1; a3 = a2; + +type B = Pick<[number], 'length'>; +declare const b: B; +b.length = 0; // Error +declare const b1: readonly [number?]; +b1.length = 0; // Error +declare const b2: readonly [number, ...number[]]; +b2.length = 0; // Error +declare const b3: readonly number[]; +b3.length = 0; // Error +declare const b4: [number?]; +b4.length = 0;