diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8daacfbaffefb..f286b1f58019a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3887,6 +3887,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 = type; resolved.members = members; @@ -10760,6 +10766,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) { @@ -10772,20 +10779,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 @@ -10813,6 +10832,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); @@ -12359,12 +12385,20 @@ namespace ts { } function getIndexSymbol(symbol: Symbol): Symbol | undefined { - return symbol.members!.get(InternalSymbolName.Index); + return symbol.members ? getIndexSymbolFromSymbolTable(symbol.members) : 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 getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { + 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); @@ -36714,6 +36748,7 @@ namespace ts { if (produceDiagnostics) { checkIndexConstraints(type); + checkIndexConstraints(staticType); checkTypeForDuplicateIndexSignatures(node); checkPropertyInitialization(node); } @@ -40100,7 +40135,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)); } } diff --git a/tests/baselines/reference/parserIndexMemberDeclaration10.errors.txt b/tests/baselines/reference/parserIndexMemberDeclaration10.errors.txt index 1e94ed36b231b..d448aaa3f294c 100644 --- a/tests/baselines/reference/parserIndexMemberDeclaration10.errors.txt +++ b/tests/baselines/reference/parserIndexMemberDeclaration10.errors.txt @@ -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. } \ No newline at end of file diff --git a/tests/baselines/reference/parserIndexMemberDeclaration6.errors.txt b/tests/baselines/reference/parserIndexMemberDeclaration6.errors.txt deleted file mode 100644 index df15ae5950e1c..0000000000000 --- a/tests/baselines/reference/parserIndexMemberDeclaration6.errors.txt +++ /dev/null @@ -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. - } \ No newline at end of file diff --git a/tests/baselines/reference/parserSymbolIndexer3.errors.txt b/tests/baselines/reference/parserSymbolIndexer3.errors.txt index 27d3a522b3ea2..617d72614658c 100644 --- a/tests/baselines/reference/parserSymbolIndexer3.errors.txt +++ b/tests/baselines/reference/parserSymbolIndexer3.errors.txt @@ -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'. } \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature1.errors.txt b/tests/baselines/reference/staticIndexSignature1.errors.txt new file mode 100644 index 0000000000000..b6bb9cf2e1c3c --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature1.errors.txt @@ -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] \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature1.js b/tests/baselines/reference/staticIndexSignature1.js new file mode 100644 index 0000000000000..8cd6b62bd4966 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature1.js @@ -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]; diff --git a/tests/baselines/reference/staticIndexSignature1.symbols b/tests/baselines/reference/staticIndexSignature1.symbols new file mode 100644 index 0000000000000..b672f4e22a7e2 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature1.symbols @@ -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)) + diff --git a/tests/baselines/reference/staticIndexSignature1.types b/tests/baselines/reference/staticIndexSignature1.types new file mode 100644 index 0000000000000..6a4de3da49568 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature1.types @@ -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 + diff --git a/tests/baselines/reference/staticIndexSignature2.errors.txt b/tests/baselines/reference/staticIndexSignature2.errors.txt new file mode 100644 index 0000000000000..8bdee878f7654 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature2.errors.txt @@ -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] \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature2.js b/tests/baselines/reference/staticIndexSignature2.js new file mode 100644 index 0000000000000..e71f351c4c4a7 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature2.js @@ -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]; diff --git a/tests/baselines/reference/staticIndexSignature2.symbols b/tests/baselines/reference/staticIndexSignature2.symbols new file mode 100644 index 0000000000000..abbf36f9733b4 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature2.symbols @@ -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)) + diff --git a/tests/baselines/reference/staticIndexSignature2.types b/tests/baselines/reference/staticIndexSignature2.types new file mode 100644 index 0000000000000..dfe75d2660096 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature2.types @@ -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 + diff --git a/tests/baselines/reference/staticIndexSignature3.js b/tests/baselines/reference/staticIndexSignature3.js new file mode 100644 index 0000000000000..6ff912caf301a --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature3.js @@ -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]; diff --git a/tests/baselines/reference/staticIndexSignature3.symbols b/tests/baselines/reference/staticIndexSignature3.symbols new file mode 100644 index 0000000000000..51a9954bf5e8f --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature3.symbols @@ -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)) + diff --git a/tests/baselines/reference/staticIndexSignature3.types b/tests/baselines/reference/staticIndexSignature3.types new file mode 100644 index 0000000000000..1e063ec1d4acd --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature3.types @@ -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 + diff --git a/tests/baselines/reference/staticIndexSignature4.errors.txt b/tests/baselines/reference/staticIndexSignature4.errors.txt new file mode 100644 index 0000000000000..c452a1105d716 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature4.errors.txt @@ -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] + } + \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature4.js b/tests/baselines/reference/staticIndexSignature4.js new file mode 100644 index 0000000000000..4ad5b347ae85b --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature4.js @@ -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]; +} diff --git a/tests/baselines/reference/staticIndexSignature4.symbols b/tests/baselines/reference/staticIndexSignature4.symbols new file mode 100644 index 0000000000000..198b01bc80288 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature4.symbols @@ -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)) +} + diff --git a/tests/baselines/reference/staticIndexSignature4.types b/tests/baselines/reference/staticIndexSignature4.types new file mode 100644 index 0000000000000..ad5bfbd44cbf2 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature4.types @@ -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 +} + diff --git a/tests/baselines/reference/staticIndexSignature5.errors.txt b/tests/baselines/reference/staticIndexSignature5.errors.txt new file mode 100644 index 0000000000000..f904ad0b6b977 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature5.errors.txt @@ -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 + type TFI = Pick + type TG = Omit + type TGI = Omit + \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature5.js b/tests/baselines/reference/staticIndexSignature5.js new file mode 100644 index 0000000000000..8d2735821ad1f --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature5.js @@ -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 +type TFI = Pick +type TG = Omit +type TGI = Omit + + +//// [staticIndexSignature5.js] +"use strict"; +var B = /** @class */ (function () { + function B() { + } + return B; +}()); diff --git a/tests/baselines/reference/staticIndexSignature5.symbols b/tests/baselines/reference/staticIndexSignature5.symbols new file mode 100644 index 0000000000000..684c403716650 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature5.symbols @@ -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 +>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 +>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 +>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 +>TGI : Symbol(TGI, Decl(staticIndexSignature5.ts, 20, 32)) +>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --)) +>I : Symbol(I, Decl(staticIndexSignature5.ts, 3, 1)) + diff --git a/tests/baselines/reference/staticIndexSignature5.types b/tests/baselines/reference/staticIndexSignature5.types new file mode 100644 index 0000000000000..92360a7fde388 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature5.types @@ -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 +>TF : TF +>B : typeof B + +type TFI = Pick +>TFI : TFI + +type TG = Omit +>TG : TG +>B : typeof B + +type TGI = Omit +>TGI : TGI + diff --git a/tests/baselines/reference/staticIndexSignature6.js b/tests/baselines/reference/staticIndexSignature6.js new file mode 100644 index 0000000000000..05eb60f92467e --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature6.js @@ -0,0 +1,36 @@ +//// [staticIndexSignature6.ts] +function foo () { + return class { + 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(); +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); diff --git a/tests/baselines/reference/staticIndexSignature6.symbols b/tests/baselines/reference/staticIndexSignature6.symbols new file mode 100644 index 0000000000000..f5905cad067db --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature6.symbols @@ -0,0 +1,46 @@ +=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts === +function foo () { +>foo : Symbol(foo, Decl(staticIndexSignature6.ts, 0, 0)) + + return class { +>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(); +>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)) + diff --git a/tests/baselines/reference/staticIndexSignature6.types b/tests/baselines/reference/staticIndexSignature6.types new file mode 100644 index 0000000000000..ecd1e24df23a7 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature6.types @@ -0,0 +1,61 @@ +=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts === +function foo () { +>foo : () => typeof (Anonymous class) + + return class { +>class { 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(); +>c : (Anonymous class) +>new C() : (Anonymous class) +>C : typeof (Anonymous class) + +c.foo(1); +>c.foo(1) : number +>c.foo : (v: number) => number +>c : (Anonymous class) +>foo : (v: number) => number +>1 : 1 + diff --git a/tests/baselines/reference/staticIndexSignature7.errors.txt b/tests/baselines/reference/staticIndexSignature7.errors.txt new file mode 100644 index 0000000000000..79bb882745144 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature7.errors.txt @@ -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'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature7.js b/tests/baselines/reference/staticIndexSignature7.js new file mode 100644 index 0000000000000..86aaa627fd1e5 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature7.js @@ -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; +}()); diff --git a/tests/baselines/reference/staticIndexSignature7.symbols b/tests/baselines/reference/staticIndexSignature7.symbols new file mode 100644 index 0000000000000..0e72acf38f4c1 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature7.symbols @@ -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)) +} + diff --git a/tests/baselines/reference/staticIndexSignature7.types b/tests/baselines/reference/staticIndexSignature7.types new file mode 100644 index 0000000000000..26c16169ea4dd --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature7.types @@ -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 +} + diff --git a/tests/baselines/reference/staticIndexer.errors.txt b/tests/baselines/reference/staticIndexer.errors.txt deleted file mode 100644 index 19ed61df658f3..0000000000000 --- a/tests/baselines/reference/staticIndexer.errors.txt +++ /dev/null @@ -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. - } \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexer.js b/tests/baselines/reference/staticIndexer.js deleted file mode 100644 index 26a0511c543ec..0000000000000 --- a/tests/baselines/reference/staticIndexer.js +++ /dev/null @@ -1,11 +0,0 @@ -//// [staticIndexer.ts] -class C { - static [s: string]: number; -} - -//// [staticIndexer.js] -var C = /** @class */ (function () { - function C() { - } - return C; -}()); diff --git a/tests/baselines/reference/staticIndexer.symbols b/tests/baselines/reference/staticIndexer.symbols deleted file mode 100644 index 8bd2376edd72d..0000000000000 --- a/tests/baselines/reference/staticIndexer.symbols +++ /dev/null @@ -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)) -} diff --git a/tests/baselines/reference/staticIndexer.types b/tests/baselines/reference/staticIndexer.types deleted file mode 100644 index 4e1a3799e59fa..0000000000000 --- a/tests/baselines/reference/staticIndexer.types +++ /dev/null @@ -1,7 +0,0 @@ -=== tests/cases/compiler/staticIndexer.ts === -class C { ->C : C - - static [s: string]: number; ->s : string -} diff --git a/tests/baselines/reference/staticIndexers.errors.txt b/tests/baselines/reference/staticIndexers.errors.txt index 8223a38a9ae40..6619a2ee93613 100644 --- a/tests/baselines/reference/staticIndexers.errors.txt +++ b/tests/baselines/reference/staticIndexers.errors.txt @@ -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 { static [x: string]: T; - ~~~~~~ -!!! error TS1071: 'static' modifier cannot appear on an index signature. ~ !!! error TS2302: Static members cannot reference class type parameters. } \ No newline at end of file diff --git a/tests/cases/compiler/staticIndexer.ts b/tests/cases/compiler/staticIndexer.ts deleted file mode 100644 index 4a73ed9c40a3f..0000000000000 --- a/tests/cases/compiler/staticIndexer.ts +++ /dev/null @@ -1,3 +0,0 @@ -class C { - static [s: string]: number; -} \ No newline at end of file diff --git a/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts new file mode 100644 index 0000000000000..94e7e1f18e3bb --- /dev/null +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts @@ -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] \ No newline at end of file diff --git a/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts new file mode 100644 index 0000000000000..67a8a5cea4dd4 --- /dev/null +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts @@ -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] \ No newline at end of file diff --git a/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts new file mode 100644 index 0000000000000..6ecf5f2ab9bd7 --- /dev/null +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts @@ -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] diff --git a/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts new file mode 100644 index 0000000000000..96e5553759a3c --- /dev/null +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts @@ -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] +} diff --git a/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts new file mode 100644 index 0000000000000..4518d54d1c9f5 --- /dev/null +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts @@ -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 +type TFI = Pick +type TG = Omit +type TGI = Omit diff --git a/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts new file mode 100644 index 0000000000000..45865c1b87dff --- /dev/null +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts @@ -0,0 +1,19 @@ +// @strict: true + +function foo () { + return class { + 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(); +c.foo(1); \ No newline at end of file diff --git a/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts new file mode 100644 index 0000000000000..a183dd35c5d4c --- /dev/null +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts @@ -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 +}