Add static index signature (#37797)

* Add static index

* fix lint

* make lint happy

* adjust test cases

* add more cases

* fix changes

* Add more case

* accept baseline

* fix error if extends others

* Update vfsUtil.ts

* use equal to empty array

* static signature of interface is an error

* Accept baseline

* Check index constraints for static signature

* Accpet baseline

* Fix crash

* fix crash

* Accept baseline

* Fix regression

* Fix crash

* always return new array
This commit is contained in:
Wenlu Wang
2021-03-27 06:30:09 +08:00
committed by GitHub
parent 2d6a490363
commit 41dc625b0a
43 changed files with 1490 additions and 70 deletions

View File

@@ -3891,6 +3891,12 @@ namespace ts {
return result || emptyArray;
}
function getNamedOrIndexSignatureMembers(members: SymbolTable): Symbol[] {
const result = getNamedMembers(members);
const index = getIndexSymbolFromSymbolTable(members);
return index ? concatenate(result, [index]) : result;
}
function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType {
const resolved = <ResolvedType>type;
resolved.members = members;
@@ -10764,6 +10770,7 @@ namespace ts {
// Combinations of function, class, enum and module
let members = emptySymbols;
let stringIndexInfo: IndexInfo | undefined;
let numberIndexInfo: IndexInfo | undefined;
if (symbol.exports) {
members = getExportsOfSymbol(symbol);
if (symbol === globalThisSymbol) {
@@ -10776,20 +10783,32 @@ namespace ts {
members = varsOnly;
}
}
let baseConstructorIndexInfo: IndexInfo | undefined;
setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined);
if (symbol.flags & SymbolFlags.Class) {
const classType = getDeclaredTypeOfClassOrInterface(symbol);
const baseConstructorType = getBaseConstructorTypeOfClass(classType);
if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) {
members = createSymbolTable(getNamedMembers(members));
members = createSymbolTable(getNamedOrIndexSignatureMembers(members));
addInheritedMembers(members, getPropertiesOfType(baseConstructorType));
}
else if (baseConstructorType === anyType) {
stringIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
baseConstructorIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
}
}
const indexSymbol = getIndexSymbolFromSymbolTable(members);
if (indexSymbol) {
stringIndexInfo = getIndexInfoOfIndexSymbol(indexSymbol, IndexKind.String);
numberIndexInfo = getIndexInfoOfIndexSymbol(indexSymbol, IndexKind.Number);
}
else {
stringIndexInfo = baseConstructorIndexInfo;
if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum ||
some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike)))) {
numberIndexInfo = enumNumberIndexInfo;
}
}
const numberIndexInfo = symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum ||
some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike))) ? enumNumberIndexInfo : undefined;
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
// We resolve the members before computing the signatures because a signature may use
// typeof with a qualified name expression that circularly references the type we are
@@ -10817,6 +10836,13 @@ namespace ts {
}
}
function getIndexInfoOfIndexSymbol(indexSymbol: Symbol, indexKind: IndexKind) {
const declaration = getIndexDeclarationOfIndexSymbol(indexSymbol, indexKind);
if (!declaration) return undefined;
return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType,
hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration);
}
function resolveReverseMappedTypeMembers(type: ReverseMappedType) {
const indexInfo = getIndexInfoOfType(type.source, IndexKind.String);
const modifiers = getMappedTypeModifiers(type.mappedType);
@@ -12363,12 +12389,20 @@ namespace ts {
}
function getIndexSymbol(symbol: Symbol): Symbol | undefined {
return symbol.members!.get(InternalSymbolName.Index);
return symbol.members ? getIndexSymbolFromSymbolTable(symbol.members) : undefined;
}
function getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined {
function getIndexSymbolFromSymbolTable(symbolTable: SymbolTable): Symbol | undefined {
return symbolTable.get(InternalSymbolName.Index);
}
function getIndexDeclarationOfSymbol(symbol: Symbol | undefined, kind: IndexKind): IndexSignatureDeclaration | undefined {
const indexSymbol = symbol && getIndexSymbol(symbol);
return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind);
}
function getIndexDeclarationOfIndexSymbol(indexSymbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined {
const syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword;
const indexSymbol = getIndexSymbol(symbol);
if (indexSymbol?.declarations) {
for (const decl of indexSymbol.declarations) {
const node = cast(decl, isIndexSignatureDeclaration);
@@ -36723,6 +36757,7 @@ namespace ts {
if (produceDiagnostics) {
checkIndexConstraints(type);
checkIndexConstraints(staticType);
checkTypeForDuplicateIndexSignatures(node);
checkPropertyInitialization(node);
}
@@ -40109,7 +40144,7 @@ namespace ts {
if (node.kind === SyntaxKind.PropertySignature || node.kind === SyntaxKind.MethodSignature) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_type_member, tokenToString(modifier.kind));
}
if (node.kind === SyntaxKind.IndexSignature) {
if (node.kind === SyntaxKind.IndexSignature && (modifier.kind !== SyntaxKind.StaticKeyword || !isClassLike(node.parent))) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_index_signature, tokenToString(modifier.kind));
}
}

View File

@@ -1,9 +1,9 @@
tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration10.ts(2,4): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration10.ts(2,11): error TS1030: 'static' modifier already seen.
==== tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration10.ts (1 errors) ====
class C {
static static [x: string]: string;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
~~~~~~
!!! error TS1030: 'static' modifier already seen.
}

View File

@@ -1,9 +0,0 @@
tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration6.ts(2,4): error TS1071: 'static' modifier cannot appear on an index signature.
==== tests/cases/conformance/parser/ecmascript5/IndexMemberDeclarations/parserIndexMemberDeclaration6.ts (1 errors) ====
class C {
static [x: string]: string;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
}

View File

@@ -1,9 +1,9 @@
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer3.ts(2,5): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer3.ts(2,13): error TS1023: An index signature parameter type must be either 'string' or 'number'.
==== tests/cases/conformance/parser/ecmascript6/Symbols/parserSymbolIndexer3.ts (1 errors) ====
class C {
static [s: symbol]: string;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
~
!!! error TS1023: An index signature parameter type must be either 'string' or 'number'.
}

View File

@@ -0,0 +1,17 @@
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts(10,1): error TS2322: Type '2' is not assignable to type '42'.
==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts (1 errors) ====
class C {
static [s: string]: number;
static [s: number]: 42
}
C["foo"] = 1
C.bar = 2;
const foo = C["foo"]
C[42] = 42
C[2] = 2;
~~~~
!!! error TS2322: Type '2' is not assignable to type '42'.
const bar = C[42]

View File

@@ -0,0 +1,25 @@
//// [staticIndexSignature1.ts]
class C {
static [s: string]: number;
static [s: number]: 42
}
C["foo"] = 1
C.bar = 2;
const foo = C["foo"]
C[42] = 42
C[2] = 2;
const bar = C[42]
//// [staticIndexSignature1.js]
var C = /** @class */ (function () {
function C() {
}
return C;
}());
C["foo"] = 1;
C.bar = 2;
var foo = C["foo"];
C[42] = 42;
C[2] = 2;
var bar = C[42];

View File

@@ -0,0 +1,31 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts ===
class C {
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
static [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature1.ts, 1, 12))
static [s: number]: 42
>s : Symbol(s, Decl(staticIndexSignature1.ts, 2, 12))
}
C["foo"] = 1
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
C.bar = 2;
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
const foo = C["foo"]
>foo : Symbol(foo, Decl(staticIndexSignature1.ts, 7, 5))
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
C[42] = 42
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
C[2] = 2;
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))
const bar = C[42]
>bar : Symbol(bar, Decl(staticIndexSignature1.ts, 10, 5))
>C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0))

View File

@@ -0,0 +1,51 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts ===
class C {
>C : C
static [s: string]: number;
>s : string
static [s: number]: 42
>s : number
}
C["foo"] = 1
>C["foo"] = 1 : 1
>C["foo"] : number
>C : typeof C
>"foo" : "foo"
>1 : 1
C.bar = 2;
>C.bar = 2 : 2
>C.bar : number
>C : typeof C
>bar : number
>2 : 2
const foo = C["foo"]
>foo : number
>C["foo"] : number
>C : typeof C
>"foo" : "foo"
C[42] = 42
>C[42] = 42 : 42
>C[42] : 42
>C : typeof C
>42 : 42
>42 : 42
C[2] = 2;
>C[2] = 2 : 2
>C[2] : 42
>C : typeof C
>2 : 2
>2 : 2
const bar = C[42]
>bar : 42
>C[42] : 42
>C : typeof C
>42 : 42

View File

@@ -0,0 +1,29 @@
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts(6,1): error TS2542: Index signature in type 'typeof C' only permits reading.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts(7,1): error TS2542: Index signature in type 'typeof C' only permits reading.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts(9,1): error TS2542: Index signature in type 'typeof C' only permits reading.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts(10,1): error TS2322: Type '2' is not assignable to type '42'.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts(10,1): error TS2542: Index signature in type 'typeof C' only permits reading.
==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts (5 errors) ====
class C {
static readonly [s: string]: number;
static readonly [s: number]: 42
}
C["foo"] = 1
~~~~~~~~
!!! error TS2542: Index signature in type 'typeof C' only permits reading.
C.bar = 2;
~~~~~
!!! error TS2542: Index signature in type 'typeof C' only permits reading.
const foo = C["foo"]
C[42] = 42
~~~~~
!!! error TS2542: Index signature in type 'typeof C' only permits reading.
C[2] = 2;
~~~~
!!! error TS2322: Type '2' is not assignable to type '42'.
~~~~
!!! error TS2542: Index signature in type 'typeof C' only permits reading.
const bar = C[42]

View File

@@ -0,0 +1,25 @@
//// [staticIndexSignature2.ts]
class C {
static readonly [s: string]: number;
static readonly [s: number]: 42
}
C["foo"] = 1
C.bar = 2;
const foo = C["foo"]
C[42] = 42
C[2] = 2;
const bar = C[42]
//// [staticIndexSignature2.js]
var C = /** @class */ (function () {
function C() {
}
return C;
}());
C["foo"] = 1;
C.bar = 2;
var foo = C["foo"];
C[42] = 42;
C[2] = 2;
var bar = C[42];

View File

@@ -0,0 +1,31 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts ===
class C {
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
static readonly [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature2.ts, 1, 21))
static readonly [s: number]: 42
>s : Symbol(s, Decl(staticIndexSignature2.ts, 2, 21))
}
C["foo"] = 1
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
C.bar = 2;
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
const foo = C["foo"]
>foo : Symbol(foo, Decl(staticIndexSignature2.ts, 7, 5))
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
C[42] = 42
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
C[2] = 2;
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))
const bar = C[42]
>bar : Symbol(bar, Decl(staticIndexSignature2.ts, 10, 5))
>C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0))

View File

@@ -0,0 +1,51 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts ===
class C {
>C : C
static readonly [s: string]: number;
>s : string
static readonly [s: number]: 42
>s : number
}
C["foo"] = 1
>C["foo"] = 1 : 1
>C["foo"] : number
>C : typeof C
>"foo" : "foo"
>1 : 1
C.bar = 2;
>C.bar = 2 : 2
>C.bar : number
>C : typeof C
>bar : number
>2 : 2
const foo = C["foo"]
>foo : number
>C["foo"] : number
>C : typeof C
>"foo" : "foo"
C[42] = 42
>C[42] = 42 : 42
>C[42] : 42
>C : typeof C
>42 : 42
>42 : 42
C[2] = 2;
>C[2] = 2 : 2
>C[2] : 42
>C : typeof C
>2 : 2
>2 : 2
const bar = C[42]
>bar : 42
>C[42] : 42
>C : typeof C
>42 : 42

View File

@@ -0,0 +1,80 @@
//// [staticIndexSignature3.ts]
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
class D extends B {
static readonly [s: string]: number
}
class ED extends D {
static readonly [s: string]: boolean
static readonly [s: number]: 1
}
class DD extends D {
static readonly [s: string]: 421
}
const a = B["f"];
const b = B[42];
const c = D["f"]
const d = D[42]
const e = ED["f"]
const f = ED[42]
const g = DD["f"]
const h = DD[42]
//// [staticIndexSignature3.js]
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var B = /** @class */ (function () {
function B() {
}
return B;
}());
var D = /** @class */ (function (_super) {
__extends(D, _super);
function D() {
return _super !== null && _super.apply(this, arguments) || this;
}
return D;
}(B));
var ED = /** @class */ (function (_super) {
__extends(ED, _super);
function ED() {
return _super !== null && _super.apply(this, arguments) || this;
}
return ED;
}(D));
var DD = /** @class */ (function (_super) {
__extends(DD, _super);
function DD() {
return _super !== null && _super.apply(this, arguments) || this;
}
return DD;
}(D));
var a = B["f"];
var b = B[42];
var c = D["f"];
var d = D[42];
var e = ED["f"];
var f = ED[42];
var g = DD["f"];
var h = DD[42];

View File

@@ -0,0 +1,70 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts ===
class B {
>B : Symbol(B, Decl(staticIndexSignature3.ts, 0, 0))
static readonly [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature3.ts, 1, 21))
static readonly [s: number]: 42 | 233
>s : Symbol(s, Decl(staticIndexSignature3.ts, 2, 21))
}
class D extends B {
>D : Symbol(D, Decl(staticIndexSignature3.ts, 3, 1))
>B : Symbol(B, Decl(staticIndexSignature3.ts, 0, 0))
static readonly [s: string]: number
>s : Symbol(s, Decl(staticIndexSignature3.ts, 6, 21))
}
class ED extends D {
>ED : Symbol(ED, Decl(staticIndexSignature3.ts, 7, 1))
>D : Symbol(D, Decl(staticIndexSignature3.ts, 3, 1))
static readonly [s: string]: boolean
>s : Symbol(s, Decl(staticIndexSignature3.ts, 10, 21))
static readonly [s: number]: 1
>s : Symbol(s, Decl(staticIndexSignature3.ts, 11, 21))
}
class DD extends D {
>DD : Symbol(DD, Decl(staticIndexSignature3.ts, 12, 1))
>D : Symbol(D, Decl(staticIndexSignature3.ts, 3, 1))
static readonly [s: string]: 421
>s : Symbol(s, Decl(staticIndexSignature3.ts, 15, 21))
}
const a = B["f"];
>a : Symbol(a, Decl(staticIndexSignature3.ts, 18, 5))
>B : Symbol(B, Decl(staticIndexSignature3.ts, 0, 0))
const b = B[42];
>b : Symbol(b, Decl(staticIndexSignature3.ts, 19, 5))
>B : Symbol(B, Decl(staticIndexSignature3.ts, 0, 0))
const c = D["f"]
>c : Symbol(c, Decl(staticIndexSignature3.ts, 20, 5))
>D : Symbol(D, Decl(staticIndexSignature3.ts, 3, 1))
const d = D[42]
>d : Symbol(d, Decl(staticIndexSignature3.ts, 21, 5))
>D : Symbol(D, Decl(staticIndexSignature3.ts, 3, 1))
const e = ED["f"]
>e : Symbol(e, Decl(staticIndexSignature3.ts, 22, 5))
>ED : Symbol(ED, Decl(staticIndexSignature3.ts, 7, 1))
const f = ED[42]
>f : Symbol(f, Decl(staticIndexSignature3.ts, 23, 5))
>ED : Symbol(ED, Decl(staticIndexSignature3.ts, 7, 1))
const g = DD["f"]
>g : Symbol(g, Decl(staticIndexSignature3.ts, 24, 5))
>DD : Symbol(DD, Decl(staticIndexSignature3.ts, 12, 1))
const h = DD[42]
>h : Symbol(h, Decl(staticIndexSignature3.ts, 25, 5))
>DD : Symbol(DD, Decl(staticIndexSignature3.ts, 12, 1))

View File

@@ -0,0 +1,86 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts ===
class B {
>B : B
static readonly [s: string]: number;
>s : string
static readonly [s: number]: 42 | 233
>s : number
}
class D extends B {
>D : D
>B : B
static readonly [s: string]: number
>s : string
}
class ED extends D {
>ED : ED
>D : D
static readonly [s: string]: boolean
>s : string
static readonly [s: number]: 1
>s : number
}
class DD extends D {
>DD : DD
>D : D
static readonly [s: string]: 421
>s : string
}
const a = B["f"];
>a : number
>B["f"] : number
>B : typeof B
>"f" : "f"
const b = B[42];
>b : 42 | 233
>B[42] : 42 | 233
>B : typeof B
>42 : 42
const c = D["f"]
>c : number
>D["f"] : number
>D : typeof D
>"f" : "f"
const d = D[42]
>d : number
>D[42] : number
>D : typeof D
>42 : 42
const e = ED["f"]
>e : boolean
>ED["f"] : boolean
>ED : typeof ED
>"f" : "f"
const f = ED[42]
>f : 1
>ED[42] : 1
>ED : typeof ED
>42 : 42
const g = DD["f"]
>g : 421
>DD["f"] : 421
>DD : typeof DD
>"f" : "f"
const h = DD[42]
>h : 421
>DD[42] : 421
>DD : typeof DD
>42 : 42

View File

@@ -0,0 +1,57 @@
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts(12,5): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts(13,5): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts(19,5): error TS2542: Index signature in type 'typeof B' only permits reading.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts(20,5): error TS2542: Index signature in type 'typeof B' only permits reading.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts(25,5): error TS2542: Index signature in type 'typeof B' only permits reading.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts(26,5): error TS2542: Index signature in type 'typeof B' only permits reading.
==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts (6 errors) ====
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
class D {
static [s: string]: number;
static [s: number]: 42 | 233
}
interface IB {
static [s: string]: number;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
static [s: number]: 42 | 233;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
}
declare const v: number
declare const i: IB
if (v === 0) {
B.a = D.a
~~~
!!! error TS2542: Index signature in type 'typeof B' only permits reading.
B[2] = D[2]
~~~~
!!! error TS2542: Index signature in type 'typeof B' only permits reading.
} else if (v === 1) {
D.a = B.a
D[2] = B[2]
} else if (v === 2) {
B.a = i.a
~~~
!!! error TS2542: Index signature in type 'typeof B' only permits reading.
B[2] = i[2]
~~~~
!!! error TS2542: Index signature in type 'typeof B' only permits reading.
D.a = i.a
D[2] = i [2]
} else if (v === 3) {
i.a = B.a
i[2] = B[2]
} else if (v === 4) {
i.a = D.a
i[2] = B[2]
}

View File

@@ -0,0 +1,72 @@
//// [staticIndexSignature4.ts]
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
class D {
static [s: string]: number;
static [s: number]: 42 | 233
}
interface IB {
static [s: string]: number;
static [s: number]: 42 | 233;
}
declare const v: number
declare const i: IB
if (v === 0) {
B.a = D.a
B[2] = D[2]
} else if (v === 1) {
D.a = B.a
D[2] = B[2]
} else if (v === 2) {
B.a = i.a
B[2] = i[2]
D.a = i.a
D[2] = i [2]
} else if (v === 3) {
i.a = B.a
i[2] = B[2]
} else if (v === 4) {
i.a = D.a
i[2] = B[2]
}
//// [staticIndexSignature4.js]
"use strict";
var B = /** @class */ (function () {
function B() {
}
return B;
}());
var D = /** @class */ (function () {
function D() {
}
return D;
}());
if (v === 0) {
B.a = D.a;
B[2] = D[2];
}
else if (v === 1) {
D.a = B.a;
D[2] = B[2];
}
else if (v === 2) {
B.a = i.a;
B[2] = i[2];
D.a = i.a;
D[2] = i[2];
}
else if (v === 3) {
i.a = B.a;
i[2] = B[2];
}
else if (v === 4) {
i.a = D.a;
i[2] = B[2];
}

View File

@@ -0,0 +1,102 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts ===
class B {
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
static readonly [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature4.ts, 1, 21))
static readonly [s: number]: 42 | 233
>s : Symbol(s, Decl(staticIndexSignature4.ts, 2, 21))
}
class D {
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
static [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature4.ts, 6, 12))
static [s: number]: 42 | 233
>s : Symbol(s, Decl(staticIndexSignature4.ts, 7, 12))
}
interface IB {
>IB : Symbol(IB, Decl(staticIndexSignature4.ts, 8, 1))
static [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature4.ts, 11, 12))
static [s: number]: 42 | 233;
>s : Symbol(s, Decl(staticIndexSignature4.ts, 12, 12))
}
declare const v: number
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
declare const i: IB
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>IB : Symbol(IB, Decl(staticIndexSignature4.ts, 8, 1))
if (v === 0) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
B.a = D.a
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
B[2] = D[2]
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
} else if (v === 1) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
D.a = B.a
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
D[2] = B[2]
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
} else if (v === 2) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
B.a = i.a
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
B[2] = i[2]
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
D.a = i.a
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
D[2] = i [2]
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
} else if (v === 3) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
i.a = B.a
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
i[2] = B[2]
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
} else if (v === 4) {
>v : Symbol(v, Decl(staticIndexSignature4.ts, 15, 13))
i.a = D.a
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>D : Symbol(D, Decl(staticIndexSignature4.ts, 3, 1))
i[2] = B[2]
>i : Symbol(i, Decl(staticIndexSignature4.ts, 16, 13))
>B : Symbol(B, Decl(staticIndexSignature4.ts, 0, 0))
}

View File

@@ -0,0 +1,169 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts ===
class B {
>B : B
static readonly [s: string]: number;
>s : string
static readonly [s: number]: 42 | 233
>s : number
}
class D {
>D : D
static [s: string]: number;
>s : string
static [s: number]: 42 | 233
>s : number
}
interface IB {
static [s: string]: number;
>s : string
static [s: number]: 42 | 233;
>s : number
}
declare const v: number
>v : number
declare const i: IB
>i : IB
if (v === 0) {
>v === 0 : boolean
>v : number
>0 : 0
B.a = D.a
>B.a = D.a : number
>B.a : number
>B : typeof B
>a : number
>D.a : number
>D : typeof D
>a : number
B[2] = D[2]
>B[2] = D[2] : 42 | 233
>B[2] : 42 | 233
>B : typeof B
>2 : 2
>D[2] : 42 | 233
>D : typeof D
>2 : 2
} else if (v === 1) {
>v === 1 : boolean
>v : number
>1 : 1
D.a = B.a
>D.a = B.a : number
>D.a : number
>D : typeof D
>a : number
>B.a : number
>B : typeof B
>a : number
D[2] = B[2]
>D[2] = B[2] : 42 | 233
>D[2] : 42 | 233
>D : typeof D
>2 : 2
>B[2] : 42 | 233
>B : typeof B
>2 : 2
} else if (v === 2) {
>v === 2 : boolean
>v : number
>2 : 2
B.a = i.a
>B.a = i.a : number
>B.a : number
>B : typeof B
>a : number
>i.a : number
>i : IB
>a : number
B[2] = i[2]
>B[2] = i[2] : 42 | 233
>B[2] : 42 | 233
>B : typeof B
>2 : 2
>i[2] : 42 | 233
>i : IB
>2 : 2
D.a = i.a
>D.a = i.a : number
>D.a : number
>D : typeof D
>a : number
>i.a : number
>i : IB
>a : number
D[2] = i [2]
>D[2] = i [2] : 42 | 233
>D[2] : 42 | 233
>D : typeof D
>2 : 2
>i [2] : 42 | 233
>i : IB
>2 : 2
} else if (v === 3) {
>v === 3 : boolean
>v : number
>3 : 3
i.a = B.a
>i.a = B.a : number
>i.a : number
>i : IB
>a : number
>B.a : number
>B : typeof B
>a : number
i[2] = B[2]
>i[2] = B[2] : 42 | 233
>i[2] : 42 | 233
>i : IB
>2 : 2
>B[2] : 42 | 233
>B : typeof B
>2 : 2
} else if (v === 4) {
>v === 4 : boolean
>v : number
>4 : 4
i.a = D.a
>i.a = D.a : number
>i.a : number
>i : IB
>a : number
>D.a : number
>D : typeof D
>a : number
i[2] = B[2]
>i[2] = B[2] : 42 | 233
>i[2] : 42 | 233
>i : IB
>2 : 2
>B[2] : 42 | 233
>B : typeof B
>2 : 2
}

View File

@@ -0,0 +1,32 @@
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts(7,5): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts(8,5): error TS1071: 'static' modifier cannot appear on an index signature.
==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts (2 errors) ====
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
interface I {
static readonly [s: string]: number;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
static readonly [s: number]: 42 | 233
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
}
type TA = (typeof B)["foo"]
type TB = (typeof B)[42]
type TC = (typeof B)[string]
type TD = (typeof B)[number]
type TE = keyof typeof B;
type TF = Pick<typeof B, number>
type TFI = Pick<I, number>
type TG = Omit<typeof B, number>
type TGI = Omit<I, number>

View File

@@ -0,0 +1,32 @@
//// [staticIndexSignature5.ts]
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
interface I {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
type TA = (typeof B)["foo"]
type TB = (typeof B)[42]
type TC = (typeof B)[string]
type TD = (typeof B)[number]
type TE = keyof typeof B;
type TF = Pick<typeof B, number>
type TFI = Pick<I, number>
type TG = Omit<typeof B, number>
type TGI = Omit<I, number>
//// [staticIndexSignature5.js]
"use strict";
var B = /** @class */ (function () {
function B() {
}
return B;
}());

View File

@@ -0,0 +1,61 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts ===
class B {
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
static readonly [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature5.ts, 1, 21))
static readonly [s: number]: 42 | 233
>s : Symbol(s, Decl(staticIndexSignature5.ts, 2, 21))
}
interface I {
>I : Symbol(I, Decl(staticIndexSignature5.ts, 3, 1))
static readonly [s: string]: number;
>s : Symbol(s, Decl(staticIndexSignature5.ts, 6, 21))
static readonly [s: number]: 42 | 233
>s : Symbol(s, Decl(staticIndexSignature5.ts, 7, 21))
}
type TA = (typeof B)["foo"]
>TA : Symbol(TA, Decl(staticIndexSignature5.ts, 8, 1))
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
type TB = (typeof B)[42]
>TB : Symbol(TB, Decl(staticIndexSignature5.ts, 10, 27))
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
type TC = (typeof B)[string]
>TC : Symbol(TC, Decl(staticIndexSignature5.ts, 11, 24))
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
type TD = (typeof B)[number]
>TD : Symbol(TD, Decl(staticIndexSignature5.ts, 13, 28))
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
type TE = keyof typeof B;
>TE : Symbol(TE, Decl(staticIndexSignature5.ts, 14, 28))
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
type TF = Pick<typeof B, number>
>TF : Symbol(TF, Decl(staticIndexSignature5.ts, 16, 25))
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
type TFI = Pick<I, number>
>TFI : Symbol(TFI, Decl(staticIndexSignature5.ts, 18, 32))
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
>I : Symbol(I, Decl(staticIndexSignature5.ts, 3, 1))
type TG = Omit<typeof B, number>
>TG : Symbol(TG, Decl(staticIndexSignature5.ts, 19, 26))
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
>B : Symbol(B, Decl(staticIndexSignature5.ts, 0, 0))
type TGI = Omit<I, number>
>TGI : Symbol(TGI, Decl(staticIndexSignature5.ts, 20, 32))
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
>I : Symbol(I, Decl(staticIndexSignature5.ts, 3, 1))

View File

@@ -0,0 +1,53 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts ===
class B {
>B : B
static readonly [s: string]: number;
>s : string
static readonly [s: number]: 42 | 233
>s : number
}
interface I {
static readonly [s: string]: number;
>s : string
static readonly [s: number]: 42 | 233
>s : number
}
type TA = (typeof B)["foo"]
>TA : number
>B : typeof B
type TB = (typeof B)[42]
>TB : 42 | 233
>B : typeof B
type TC = (typeof B)[string]
>TC : number
>B : typeof B
type TD = (typeof B)[number]
>TD : 42 | 233
>B : typeof B
type TE = keyof typeof B;
>TE : string | number
>B : typeof B
type TF = Pick<typeof B, number>
>TF : TF
>B : typeof B
type TFI = Pick<I, number>
>TFI : TFI
type TG = Omit<typeof B, number>
>TG : TG
>B : typeof B
type TGI = Omit<I, number>
>TGI : TGI

View File

@@ -0,0 +1,36 @@
//// [staticIndexSignature6.ts]
function foo () {
return class<T> {
static [s: string]: number
static [s: number]: 42
foo(v: T) { return v }
}
}
const C = foo()
C.a;
C.a = 1;
C[2];
C[2] = 42;
const c = new C<number>();
c.foo(1);
//// [staticIndexSignature6.js]
"use strict";
function foo() {
return /** @class */ (function () {
function class_1() {
}
class_1.prototype.foo = function (v) { return v; };
return class_1;
}());
}
var C = foo();
C.a;
C.a = 1;
C[2];
C[2] = 42;
var c = new C();
c.foo(1);

View File

@@ -0,0 +1,46 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts ===
function foo () {
>foo : Symbol(foo, Decl(staticIndexSignature6.ts, 0, 0))
return class<T> {
>T : Symbol(T, Decl(staticIndexSignature6.ts, 1, 17))
static [s: string]: number
>s : Symbol(s, Decl(staticIndexSignature6.ts, 2, 16))
static [s: number]: 42
>s : Symbol(s, Decl(staticIndexSignature6.ts, 3, 16))
foo(v: T) { return v }
>foo : Symbol((Anonymous class).foo, Decl(staticIndexSignature6.ts, 3, 30))
>v : Symbol(v, Decl(staticIndexSignature6.ts, 5, 12))
>T : Symbol(T, Decl(staticIndexSignature6.ts, 1, 17))
>v : Symbol(v, Decl(staticIndexSignature6.ts, 5, 12))
}
}
const C = foo()
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
>foo : Symbol(foo, Decl(staticIndexSignature6.ts, 0, 0))
C.a;
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
C.a = 1;
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
C[2];
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
C[2] = 42;
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
const c = new C<number>();
>c : Symbol(c, Decl(staticIndexSignature6.ts, 15, 5))
>C : Symbol(C, Decl(staticIndexSignature6.ts, 9, 5))
c.foo(1);
>c.foo : Symbol((Anonymous class).foo, Decl(staticIndexSignature6.ts, 3, 30))
>c : Symbol(c, Decl(staticIndexSignature6.ts, 15, 5))
>foo : Symbol((Anonymous class).foo, Decl(staticIndexSignature6.ts, 3, 30))

View File

@@ -0,0 +1,61 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts ===
function foo () {
>foo : () => typeof (Anonymous class)
return class<T> {
>class<T> { static [s: string]: number static [s: number]: 42 foo(v: T) { return v } } : typeof (Anonymous class)
static [s: string]: number
>s : string
static [s: number]: 42
>s : number
foo(v: T) { return v }
>foo : (v: T) => T
>v : T
>v : T
}
}
const C = foo()
>C : typeof (Anonymous class)
>foo() : typeof (Anonymous class)
>foo : () => typeof (Anonymous class)
C.a;
>C.a : number
>C : typeof (Anonymous class)
>a : number
C.a = 1;
>C.a = 1 : 1
>C.a : number
>C : typeof (Anonymous class)
>a : number
>1 : 1
C[2];
>C[2] : 42
>C : typeof (Anonymous class)
>2 : 2
C[2] = 42;
>C[2] = 42 : 42
>C[2] : 42
>C : typeof (Anonymous class)
>2 : 2
>42 : 42
const c = new C<number>();
>c : (Anonymous class)<number>
>new C<number>() : (Anonymous class)<number>
>C : typeof (Anonymous class)
c.foo(1);
>c.foo(1) : number
>c.foo : (v: number) => number
>c : (Anonymous class)<number>
>foo : (v: number) => number
>1 : 1

View File

@@ -0,0 +1,18 @@
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts(3,12): error TS2411: Property 'x' of type 'number' is not assignable to string index type 'string'.
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts(7,12): error TS2411: Property 'foo' of type '() => void' is not assignable to string index type 'string'.
==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts (2 errors) ====
class X {
static [index: string]: string;
static x = 12; // Should error, incompatible with index signature
~
!!! error TS2411: Property 'x' of type 'number' is not assignable to string index type 'string'.
}
class Y {
static [index: string]: string;
static foo() {} // should error, incompatible with index signature
~~~
!!! error TS2411: Property 'foo' of type '() => void' is not assignable to string index type 'string'.
}

View File

@@ -0,0 +1,25 @@
//// [staticIndexSignature7.ts]
class X {
static [index: string]: string;
static x = 12; // Should error, incompatible with index signature
}
class Y {
static [index: string]: string;
static foo() {} // should error, incompatible with index signature
}
//// [staticIndexSignature7.js]
"use strict";
var X = /** @class */ (function () {
function X() {
}
X.x = 12; // Should error, incompatible with index signature
return X;
}());
var Y = /** @class */ (function () {
function Y() {
}
Y.foo = function () { }; // should error, incompatible with index signature
return Y;
}());

View File

@@ -0,0 +1,20 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts ===
class X {
>X : Symbol(X, Decl(staticIndexSignature7.ts, 0, 0))
static [index: string]: string;
>index : Symbol(index, Decl(staticIndexSignature7.ts, 1, 12))
static x = 12; // Should error, incompatible with index signature
>x : Symbol(X.x, Decl(staticIndexSignature7.ts, 1, 35))
}
class Y {
>Y : Symbol(Y, Decl(staticIndexSignature7.ts, 3, 1))
static [index: string]: string;
>index : Symbol(index, Decl(staticIndexSignature7.ts, 5, 12))
static foo() {} // should error, incompatible with index signature
>foo : Symbol(Y.foo, Decl(staticIndexSignature7.ts, 5, 35))
}

View File

@@ -0,0 +1,21 @@
=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts ===
class X {
>X : X
static [index: string]: string;
>index : string
static x = 12; // Should error, incompatible with index signature
>x : number
>12 : 12
}
class Y {
>Y : Y
static [index: string]: string;
>index : string
static foo() {} // should error, incompatible with index signature
>foo : () => void
}

View File

@@ -1,9 +0,0 @@
tests/cases/compiler/staticIndexer.ts(2,5): error TS1071: 'static' modifier cannot appear on an index signature.
==== tests/cases/compiler/staticIndexer.ts (1 errors) ====
class C {
static [s: string]: number;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
}

View File

@@ -1,11 +0,0 @@
//// [staticIndexer.ts]
class C {
static [s: string]: number;
}
//// [staticIndexer.js]
var C = /** @class */ (function () {
function C() {
}
return C;
}());

View File

@@ -1,7 +0,0 @@
=== tests/cases/compiler/staticIndexer.ts ===
class C {
>C : Symbol(C, Decl(staticIndexer.ts, 0, 0))
static [s: string]: number;
>s : Symbol(s, Decl(staticIndexer.ts, 1, 12))
}

View File

@@ -1,7 +0,0 @@
=== tests/cases/compiler/staticIndexer.ts ===
class C {
>C : C
static [s: string]: number;
>s : string
}

View File

@@ -1,28 +1,19 @@
tests/cases/conformance/classes/indexMemberDeclarations/staticIndexers.ts(4,5): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/classes/indexMemberDeclarations/staticIndexers.ts(8,5): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/classes/indexMemberDeclarations/staticIndexers.ts(12,5): error TS1071: 'static' modifier cannot appear on an index signature.
tests/cases/conformance/classes/indexMemberDeclarations/staticIndexers.ts(12,25): error TS2302: Static members cannot reference class type parameters.
==== tests/cases/conformance/classes/indexMemberDeclarations/staticIndexers.ts (4 errors) ====
==== tests/cases/conformance/classes/indexMemberDeclarations/staticIndexers.ts (1 errors) ====
// static indexers not allowed
class C {
static [x: string]: string;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
}
class D {
static [x: number]: string;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
}
class E<T> {
static [x: string]: T;
~~~~~~
!!! error TS1071: 'static' modifier cannot appear on an index signature.
~
!!! error TS2302: Static members cannot reference class type parameters.
}

View File

@@ -1,3 +0,0 @@
class C {
static [s: string]: number;
}

View File

@@ -0,0 +1,11 @@
class C {
static [s: string]: number;
static [s: number]: 42
}
C["foo"] = 1
C.bar = 2;
const foo = C["foo"]
C[42] = 42
C[2] = 2;
const bar = C[42]

View File

@@ -0,0 +1,11 @@
class C {
static readonly [s: string]: number;
static readonly [s: number]: 42
}
C["foo"] = 1
C.bar = 2;
const foo = C["foo"]
C[42] = 42
C[2] = 2;
const bar = C[42]

View File

@@ -0,0 +1,28 @@
// @strict: true
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
class D extends B {
static readonly [s: string]: number
}
class ED extends D {
static readonly [s: string]: boolean
static readonly [s: number]: 1
}
class DD extends D {
static readonly [s: string]: 421
}
const a = B["f"];
const b = B[42];
const c = D["f"]
const d = D[42]
const e = ED["f"]
const f = ED[42]
const g = DD["f"]
const h = DD[42]

View File

@@ -0,0 +1,37 @@
// @strict: true
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
class D {
static [s: string]: number;
static [s: number]: 42 | 233
}
interface IB {
static [s: string]: number;
static [s: number]: 42 | 233;
}
declare const v: number
declare const i: IB
if (v === 0) {
B.a = D.a
B[2] = D[2]
} else if (v === 1) {
D.a = B.a
D[2] = B[2]
} else if (v === 2) {
B.a = i.a
B[2] = i[2]
D.a = i.a
D[2] = i [2]
} else if (v === 3) {
i.a = B.a
i[2] = B[2]
} else if (v === 4) {
i.a = D.a
i[2] = B[2]
}

View File

@@ -0,0 +1,24 @@
// @strict: true
class B {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
interface I {
static readonly [s: string]: number;
static readonly [s: number]: 42 | 233
}
type TA = (typeof B)["foo"]
type TB = (typeof B)[42]
type TC = (typeof B)[string]
type TD = (typeof B)[number]
type TE = keyof typeof B;
type TF = Pick<typeof B, number>
type TFI = Pick<I, number>
type TG = Omit<typeof B, number>
type TGI = Omit<I, number>

View File

@@ -0,0 +1,19 @@
// @strict: true
function foo () {
return class<T> {
static [s: string]: number
static [s: number]: 42
foo(v: T) { return v }
}
}
const C = foo()
C.a;
C.a = 1;
C[2];
C[2] = 42;
const c = new C<number>();
c.foo(1);

View File

@@ -0,0 +1,9 @@
// @strict: true
class X {
static [index: string]: string;
static x = 12; // Should error, incompatible with index signature
}
class Y {
static [index: string]: string;
static foo() {} // should error, incompatible with index signature
}