From ed1a7989bacb3b1bc2bac748631f1d2fe321f3b5 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 5 Apr 2020 12:19:32 +0800 Subject: [PATCH 01/21] Add static index --- src/compiler/checker.ts | 58 +++++++++++++------ src/compiler/parser.ts | 5 ++ src/compiler/types.ts | 1 + .../reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + .../parserIndexMemberDeclaration10.errors.txt | 6 +- .../parserIndexMemberDeclaration6.errors.txt | 9 --- .../reference/parserSymbolIndexer3.errors.txt | 6 +- .../reference/staticAsIdentifier.errors.txt | 6 +- .../staticIndexSignature1.errors.txt | 17 ++++++ .../reference/staticIndexSignature1.js | 25 ++++++++ .../reference/staticIndexSignature1.symbols | 31 ++++++++++ .../reference/staticIndexSignature1.types | 51 ++++++++++++++++ .../staticIndexSignature2.errors.txt | 29 ++++++++++ .../reference/staticIndexSignature2.js | 25 ++++++++ .../reference/staticIndexSignature2.symbols | 31 ++++++++++ .../reference/staticIndexSignature2.types | 51 ++++++++++++++++ .../reference/staticIndexer.errors.txt | 9 --- .../reference/staticIndexers.errors.txt | 11 +--- tests/cases/compiler/staticIndexSignature1.ts | 12 ++++ tests/cases/compiler/staticIndexSignature2.ts | 12 ++++ 21 files changed, 343 insertions(+), 54 deletions(-) delete mode 100644 tests/baselines/reference/parserIndexMemberDeclaration6.errors.txt create mode 100644 tests/baselines/reference/staticIndexSignature1.errors.txt create mode 100644 tests/baselines/reference/staticIndexSignature1.js create mode 100644 tests/baselines/reference/staticIndexSignature1.symbols create mode 100644 tests/baselines/reference/staticIndexSignature1.types create mode 100644 tests/baselines/reference/staticIndexSignature2.errors.txt create mode 100644 tests/baselines/reference/staticIndexSignature2.js create mode 100644 tests/baselines/reference/staticIndexSignature2.symbols create mode 100644 tests/baselines/reference/staticIndexSignature2.types delete mode 100644 tests/baselines/reference/staticIndexer.errors.txt create mode 100644 tests/cases/compiler/staticIndexSignature1.ts create mode 100644 tests/cases/compiler/staticIndexSignature2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 7bd58c379eac9..32bdfa0e22cae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8864,8 +8864,8 @@ namespace ts { if (merged) { // note:we overwrite links because we just cloned the symbol symbol = links = merged; - } - + } + const type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol); const outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); const localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); @@ -9904,6 +9904,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) { @@ -9916,6 +9917,7 @@ namespace ts { members = varsOnly; } } + let baseConstructorIndexInfo: IndexInfo | undefined; setStructuredTypeMembers(type, members, emptyArray, emptyArray, undefined, undefined); if (symbol.flags & SymbolFlags.Class) { const classType = getDeclaredTypeOfClassOrInterface(symbol); @@ -9925,11 +9927,21 @@ namespace ts { 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 @@ -9957,6 +9969,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, + hasModifier(declaration, ModifierFlags.Readonly), declaration); + } + function resolveReverseMappedTypeMembers(type: ReverseMappedType) { const indexInfo = getIndexInfoOfType(type.source, IndexKind.String); const modifiers = getMappedTypeModifiers(type.mappedType); @@ -11433,24 +11452,29 @@ namespace ts { } function getIndexSymbol(symbol: Symbol): Symbol | undefined { - return symbol.members!.get(InternalSymbolName.Index); + return getIndexSymbolFromSymbolTable(symbol.members!); + } + + function getIndexSymbolFromSymbolTable(symbolTable: SymbolTable): Symbol | undefined { + return symbolTable.get(InternalSymbolName.Index); } function getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { - const syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword; const indexSymbol = getIndexSymbol(symbol); - if (indexSymbol) { - for (const decl of indexSymbol.declarations) { - const node = cast(decl, isIndexSignatureDeclaration); - if (node.parameters.length === 1) { - const parameter = node.parameters[0]; - if (parameter.type && parameter.type.kind === syntaxKind) { - return node; - } + return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind); + } + + function getIndexDeclarationOfIndexSymbol(indexSymbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { + const syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword; + for (const decl of indexSymbol.declarations) { + const node = cast(decl, isIndexSignatureDeclaration); + if (node.parameters.length === 1) { + const parameter = node.parameters[0]; + if (parameter.type && parameter.type.kind === syntaxKind) { + return node; } } } - return undefined; } @@ -36912,7 +36936,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) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_an_index_signature, tokenToString(modifier.kind)); } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 9754cdf64d362..aec642d62244d 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2829,6 +2829,10 @@ namespace ts { } function isIndexSignature(): boolean { + return token() === SyntaxKind.StaticKeyword ? lookAhead(isNonStaticIndexSignature) : isNonStaticIndexSignature() + } + + function isNonStaticIndexSignature(): boolean { return token() === SyntaxKind.OpenBracketToken && lookAhead(isUnambiguouslyIndexSignature); } @@ -2889,6 +2893,7 @@ namespace ts { function parseIndexSignatureDeclaration(node: IndexSignatureDeclaration): IndexSignatureDeclaration { node.kind = SyntaxKind.IndexSignature; + node.staticModifier = parseOptionalToken(SyntaxKind.StaticKeyword); node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); node.type = parseTypeAnnotation(); parseTypeMemberSemicolon(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0c45dca9529fc..350166a427b21 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1187,6 +1187,7 @@ namespace ts { export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { kind: SyntaxKind.IndexSignature; parent: ObjectTypeDeclaration; + staticModifier?: Token; } export interface TypeNode extends Node { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index e89d9461ff314..cb9556c4c0a9a 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -754,6 +754,7 @@ declare namespace ts { export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { kind: SyntaxKind.IndexSignature; parent: ObjectTypeDeclaration; + staticModifier?: Token; } export interface TypeNode extends Node { _typeNodeBrand: any; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 2213fd4be6a66..a2a86b6f30df7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -754,6 +754,7 @@ declare namespace ts { export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { kind: SyntaxKind.IndexSignature; parent: ObjectTypeDeclaration; + staticModifier?: Token; } export interface TypeNode extends Node { _typeNodeBrand: any; 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/staticAsIdentifier.errors.txt b/tests/baselines/reference/staticAsIdentifier.errors.txt index 4173b0b14c5d3..52108a5a2214b 100644 --- a/tests/baselines/reference/staticAsIdentifier.errors.txt +++ b/tests/baselines/reference/staticAsIdentifier.errors.txt @@ -1,10 +1,10 @@ -tests/cases/compiler/staticAsIdentifier.ts(2,5): error TS1071: 'static' modifier cannot appear on an index signature. +tests/cases/compiler/staticAsIdentifier.ts(2,12): error TS1030: 'static' modifier already seen. ==== tests/cases/compiler/staticAsIdentifier.ts (1 errors) ==== class C { static static - ~~~~~~ -!!! error TS1071: 'static' modifier cannot appear on an index signature. + ~~~~~~ +!!! error TS1030: 'static' modifier already seen. [x: string]: string; } \ 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..ffc3f9acffb73 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature1.errors.txt @@ -0,0 +1,17 @@ +tests/cases/compiler/staticIndexSignature1.ts(10,1): error TS2322: Type '2' is not assignable to type '42'. + + +==== tests/cases/compiler/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..5868eb4fdc0f3 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature1.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/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..e97b393bc7b9e --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature1.types @@ -0,0 +1,51 @@ +=== tests/cases/compiler/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..dab2c24944979 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature2.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/staticIndexSignature2.ts(6,1): error TS2542: Index signature in type 'typeof C' only permits reading. +tests/cases/compiler/staticIndexSignature2.ts(7,1): error TS2542: Index signature in type 'typeof C' only permits reading. +tests/cases/compiler/staticIndexSignature2.ts(9,1): error TS2542: Index signature in type 'typeof C' only permits reading. +tests/cases/compiler/staticIndexSignature2.ts(10,1): error TS2322: Type '2' is not assignable to type '42'. +tests/cases/compiler/staticIndexSignature2.ts(10,1): error TS2542: Index signature in type 'typeof C' only permits reading. + + +==== tests/cases/compiler/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..eb6331b30f6b2 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature2.symbols @@ -0,0 +1,31 @@ +=== tests/cases/compiler/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..5121786907a98 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature2.types @@ -0,0 +1,51 @@ +=== tests/cases/compiler/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/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/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/staticIndexSignature1.ts b/tests/cases/compiler/staticIndexSignature1.ts new file mode 100644 index 0000000000000..edc6575530feb --- /dev/null +++ b/tests/cases/compiler/staticIndexSignature1.ts @@ -0,0 +1,12 @@ +// @skipLibCheck: true +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/compiler/staticIndexSignature2.ts b/tests/cases/compiler/staticIndexSignature2.ts new file mode 100644 index 0000000000000..3df6c1b48da44 --- /dev/null +++ b/tests/cases/compiler/staticIndexSignature2.ts @@ -0,0 +1,12 @@ +// @skipLibCheck: true +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 From f83b7de56de01ebd5cab67473f0bced736bbdc26 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 5 Apr 2020 13:04:23 +0800 Subject: [PATCH 02/21] fix lint --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 32bdfa0e22cae..372fda2440703 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8864,8 +8864,8 @@ namespace ts { if (merged) { // note:we overwrite links because we just cloned the symbol symbol = links = merged; - } - + } + const type = originalLinks.declaredType = links.declaredType = createObjectType(kind, symbol); const outerTypeParameters = getOuterTypeParametersOfClassOrInterface(symbol); const localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); From d6fdab8bb1ee699ad3670140378dfcdb0d2cce9b Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 5 Apr 2020 13:07:56 +0800 Subject: [PATCH 03/21] make lint happy --- src/compiler/checker.ts | 5 +++-- src/compiler/parser.ts | 5 ----- src/compiler/types.ts | 1 - tests/baselines/reference/api/tsserverlibrary.d.ts | 1 - tests/baselines/reference/api/typescript.d.ts | 1 - 5 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 372fda2440703..e118403e407c8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9938,7 +9938,8 @@ namespace ts { } else { stringIndexInfo = baseConstructorIndexInfo; - if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum || some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike))) ) { + if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum || + some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike)))) { numberIndexInfo = enumNumberIndexInfo; } } @@ -9973,7 +9974,7 @@ namespace ts { const declaration = getIndexDeclarationOfIndexSymbol(indexSymbol, indexKind); if (!declaration) return undefined; return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - hasModifier(declaration, ModifierFlags.Readonly), declaration); + hasModifier(declaration, ModifierFlags.Readonly), declaration); } function resolveReverseMappedTypeMembers(type: ReverseMappedType) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index aec642d62244d..9754cdf64d362 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2829,10 +2829,6 @@ namespace ts { } function isIndexSignature(): boolean { - return token() === SyntaxKind.StaticKeyword ? lookAhead(isNonStaticIndexSignature) : isNonStaticIndexSignature() - } - - function isNonStaticIndexSignature(): boolean { return token() === SyntaxKind.OpenBracketToken && lookAhead(isUnambiguouslyIndexSignature); } @@ -2893,7 +2889,6 @@ namespace ts { function parseIndexSignatureDeclaration(node: IndexSignatureDeclaration): IndexSignatureDeclaration { node.kind = SyntaxKind.IndexSignature; - node.staticModifier = parseOptionalToken(SyntaxKind.StaticKeyword); node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken); node.type = parseTypeAnnotation(); parseTypeMemberSemicolon(); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 350166a427b21..0c45dca9529fc 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1187,7 +1187,6 @@ namespace ts { export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { kind: SyntaxKind.IndexSignature; parent: ObjectTypeDeclaration; - staticModifier?: Token; } export interface TypeNode extends Node { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index cb9556c4c0a9a..e89d9461ff314 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -754,7 +754,6 @@ declare namespace ts { export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { kind: SyntaxKind.IndexSignature; parent: ObjectTypeDeclaration; - staticModifier?: Token; } export interface TypeNode extends Node { _typeNodeBrand: any; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index a2a86b6f30df7..2213fd4be6a66 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -754,7 +754,6 @@ declare namespace ts { export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement { kind: SyntaxKind.IndexSignature; parent: ObjectTypeDeclaration; - staticModifier?: Token; } export interface TypeNode extends Node { _typeNodeBrand: any; From 8eca2beb2e9104da93ec2e28d4f5078e869ca142 Mon Sep 17 00:00:00 2001 From: kingwl Date: Thu, 30 Apr 2020 17:33:34 +0800 Subject: [PATCH 04/21] adjust test cases --- .../baselines/reference/staticAsIdentifier.errors.txt | 4 ++++ tests/baselines/reference/staticAsIdentifier.js | 9 +++++++++ tests/baselines/reference/staticAsIdentifier.symbols | 7 +++++++ tests/baselines/reference/staticAsIdentifier.types | 7 +++++++ tests/baselines/reference/staticIndexer.js | 11 ----------- tests/baselines/reference/staticIndexer.symbols | 7 ------- tests/baselines/reference/staticIndexer.types | 7 ------- tests/cases/compiler/staticAsIdentifier.ts | 4 ++++ tests/cases/compiler/staticIndexer.ts | 3 --- 9 files changed, 31 insertions(+), 28 deletions(-) delete mode 100644 tests/baselines/reference/staticIndexer.js delete mode 100644 tests/baselines/reference/staticIndexer.symbols delete mode 100644 tests/baselines/reference/staticIndexer.types delete mode 100644 tests/cases/compiler/staticIndexer.ts diff --git a/tests/baselines/reference/staticAsIdentifier.errors.txt b/tests/baselines/reference/staticAsIdentifier.errors.txt index 52108a5a2214b..c4d6ea7d0fd76 100644 --- a/tests/baselines/reference/staticAsIdentifier.errors.txt +++ b/tests/baselines/reference/staticAsIdentifier.errors.txt @@ -7,4 +7,8 @@ tests/cases/compiler/staticAsIdentifier.ts(2,12): error TS1030: 'static' modifie ~~~~~~ !!! error TS1030: 'static' modifier already seen. [x: string]: string; + } + + class CC { + static static; } \ No newline at end of file diff --git a/tests/baselines/reference/staticAsIdentifier.js b/tests/baselines/reference/staticAsIdentifier.js index d04fd375be5d0..a4dcd070ea886 100644 --- a/tests/baselines/reference/staticAsIdentifier.js +++ b/tests/baselines/reference/staticAsIdentifier.js @@ -2,6 +2,10 @@ class C { static static [x: string]: string; +} + +class CC { + static static; } //// [staticAsIdentifier.js] @@ -10,3 +14,8 @@ var C = /** @class */ (function () { } return C; }()); +var CC = /** @class */ (function () { + function CC() { + } + return CC; +}()); diff --git a/tests/baselines/reference/staticAsIdentifier.symbols b/tests/baselines/reference/staticAsIdentifier.symbols index c5f37ddd1f80a..ec2e7a478ac18 100644 --- a/tests/baselines/reference/staticAsIdentifier.symbols +++ b/tests/baselines/reference/staticAsIdentifier.symbols @@ -6,3 +6,10 @@ class C { [x: string]: string; >x : Symbol(x, Decl(staticAsIdentifier.ts, 2, 5)) } + +class CC { +>CC : Symbol(CC, Decl(staticAsIdentifier.ts, 3, 1)) + + static static; +>static : Symbol(CC.static, Decl(staticAsIdentifier.ts, 5, 10)) +} diff --git a/tests/baselines/reference/staticAsIdentifier.types b/tests/baselines/reference/staticAsIdentifier.types index 05608dce146b1..786fc4a77b0f7 100644 --- a/tests/baselines/reference/staticAsIdentifier.types +++ b/tests/baselines/reference/staticAsIdentifier.types @@ -6,3 +6,10 @@ class C { [x: string]: string; >x : string } + +class CC { +>CC : CC + + static static; +>static : any +} 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/cases/compiler/staticAsIdentifier.ts b/tests/cases/compiler/staticAsIdentifier.ts index 3cccca3bf8874..f6e97e6ab94ff 100644 --- a/tests/cases/compiler/staticAsIdentifier.ts +++ b/tests/cases/compiler/staticAsIdentifier.ts @@ -1,4 +1,8 @@ class C { static static [x: string]: string; +} + +class CC { + static static; } \ 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 From b7f614fbd15b2c6a2c24f7a36ebcad394095114a Mon Sep 17 00:00:00 2001 From: kingwl Date: Wed, 20 May 2020 20:34:12 +0800 Subject: [PATCH 05/21] add more cases --- src/harness/vfsUtil.ts | 2 +- .../staticIndexSignature1.errors.txt | 4 +- .../reference/staticIndexSignature1.symbols | 2 +- .../reference/staticIndexSignature1.types | 2 +- .../staticIndexSignature2.errors.txt | 12 +- .../reference/staticIndexSignature2.symbols | 2 +- .../reference/staticIndexSignature2.types | 2 +- .../staticIndexSignature3.errors.txt | 60 +++++++ .../reference/staticIndexSignature3.js | 78 ++++++++ .../reference/staticIndexSignature3.symbols | 70 ++++++++ .../reference/staticIndexSignature3.types | 86 +++++++++ .../staticIndexSignature4.errors.txt | 51 ++++++ .../reference/staticIndexSignature4.js | 72 ++++++++ .../reference/staticIndexSignature4.symbols | 102 +++++++++++ .../reference/staticIndexSignature4.types | 169 ++++++++++++++++++ .../reference/staticIndexSignature5.js | 32 ++++ .../reference/staticIndexSignature5.symbols | 61 +++++++ .../reference/staticIndexSignature5.types | 53 ++++++ .../staticIndexSignature1.ts | 1 - .../staticIndexSignature2.ts | 1 - .../staticIndexSignature3.ts | 28 +++ .../staticIndexSignature4.ts | 37 ++++ .../staticIndexSignature5.ts | 24 +++ 23 files changed, 936 insertions(+), 15 deletions(-) create mode 100644 tests/baselines/reference/staticIndexSignature3.errors.txt create mode 100644 tests/baselines/reference/staticIndexSignature3.js create mode 100644 tests/baselines/reference/staticIndexSignature3.symbols create mode 100644 tests/baselines/reference/staticIndexSignature3.types create mode 100644 tests/baselines/reference/staticIndexSignature4.errors.txt create mode 100644 tests/baselines/reference/staticIndexSignature4.js create mode 100644 tests/baselines/reference/staticIndexSignature4.symbols create mode 100644 tests/baselines/reference/staticIndexSignature4.types create mode 100644 tests/baselines/reference/staticIndexSignature5.js create mode 100644 tests/baselines/reference/staticIndexSignature5.symbols create mode 100644 tests/baselines/reference/staticIndexSignature5.types rename tests/cases/{compiler => conformance/classes/staticIndexSignature}/staticIndexSignature1.ts (87%) rename tests/cases/{compiler => conformance/classes/staticIndexSignature}/staticIndexSignature2.ts (88%) create mode 100644 tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts create mode 100644 tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts create mode 100644 tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature5.ts diff --git a/src/harness/vfsUtil.ts b/src/harness/vfsUtil.ts index 88fc73ebca9be..c2dc94d781031 100644 --- a/src/harness/vfsUtil.ts +++ b/src/harness/vfsUtil.ts @@ -663,7 +663,7 @@ namespace vfs { if (!isFile(node)) throw createIOError("EBADF"); const buffer = this._getBuffer(node).slice(); - return encoding ? buffer.toString(encoding) : buffer; + return encoding ? buffer.toString(encoding as any) : buffer; } /** diff --git a/tests/baselines/reference/staticIndexSignature1.errors.txt b/tests/baselines/reference/staticIndexSignature1.errors.txt index ffc3f9acffb73..b6bb9cf2e1c3c 100644 --- a/tests/baselines/reference/staticIndexSignature1.errors.txt +++ b/tests/baselines/reference/staticIndexSignature1.errors.txt @@ -1,7 +1,7 @@ -tests/cases/compiler/staticIndexSignature1.ts(10,1): error TS2322: Type '2' is not assignable to type '42'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts(10,1): error TS2322: Type '2' is not assignable to type '42'. -==== tests/cases/compiler/staticIndexSignature1.ts (1 errors) ==== +==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts (1 errors) ==== class C { static [s: string]: number; static [s: number]: 42 diff --git a/tests/baselines/reference/staticIndexSignature1.symbols b/tests/baselines/reference/staticIndexSignature1.symbols index 5868eb4fdc0f3..b672f4e22a7e2 100644 --- a/tests/baselines/reference/staticIndexSignature1.symbols +++ b/tests/baselines/reference/staticIndexSignature1.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/staticIndexSignature1.ts === +=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts === class C { >C : Symbol(C, Decl(staticIndexSignature1.ts, 0, 0)) diff --git a/tests/baselines/reference/staticIndexSignature1.types b/tests/baselines/reference/staticIndexSignature1.types index e97b393bc7b9e..6a4de3da49568 100644 --- a/tests/baselines/reference/staticIndexSignature1.types +++ b/tests/baselines/reference/staticIndexSignature1.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/staticIndexSignature1.ts === +=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts === class C { >C : C diff --git a/tests/baselines/reference/staticIndexSignature2.errors.txt b/tests/baselines/reference/staticIndexSignature2.errors.txt index dab2c24944979..8bdee878f7654 100644 --- a/tests/baselines/reference/staticIndexSignature2.errors.txt +++ b/tests/baselines/reference/staticIndexSignature2.errors.txt @@ -1,11 +1,11 @@ -tests/cases/compiler/staticIndexSignature2.ts(6,1): error TS2542: Index signature in type 'typeof C' only permits reading. -tests/cases/compiler/staticIndexSignature2.ts(7,1): error TS2542: Index signature in type 'typeof C' only permits reading. -tests/cases/compiler/staticIndexSignature2.ts(9,1): error TS2542: Index signature in type 'typeof C' only permits reading. -tests/cases/compiler/staticIndexSignature2.ts(10,1): error TS2322: Type '2' is not assignable to type '42'. -tests/cases/compiler/staticIndexSignature2.ts(10,1): error TS2542: Index signature in type 'typeof C' only permits reading. +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/compiler/staticIndexSignature2.ts (5 errors) ==== +==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts (5 errors) ==== class C { static readonly [s: string]: number; static readonly [s: number]: 42 diff --git a/tests/baselines/reference/staticIndexSignature2.symbols b/tests/baselines/reference/staticIndexSignature2.symbols index eb6331b30f6b2..abbf36f9733b4 100644 --- a/tests/baselines/reference/staticIndexSignature2.symbols +++ b/tests/baselines/reference/staticIndexSignature2.symbols @@ -1,4 +1,4 @@ -=== tests/cases/compiler/staticIndexSignature2.ts === +=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts === class C { >C : Symbol(C, Decl(staticIndexSignature2.ts, 0, 0)) diff --git a/tests/baselines/reference/staticIndexSignature2.types b/tests/baselines/reference/staticIndexSignature2.types index 5121786907a98..dfe75d2660096 100644 --- a/tests/baselines/reference/staticIndexSignature2.types +++ b/tests/baselines/reference/staticIndexSignature2.types @@ -1,4 +1,4 @@ -=== tests/cases/compiler/staticIndexSignature2.ts === +=== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts === class C { >C : C diff --git a/tests/baselines/reference/staticIndexSignature3.errors.txt b/tests/baselines/reference/staticIndexSignature3.errors.txt new file mode 100644 index 0000000000000..b6fa831450b62 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature3.errors.txt @@ -0,0 +1,60 @@ +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(21,11): error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof D'. + Property 'f' does not exist on type 'typeof D'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(22,11): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof D'. + Property '42' does not exist on type 'typeof D'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(23,11): error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof ED'. + Property 'f' does not exist on type 'typeof ED'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(24,11): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof ED'. + Property '42' does not exist on type 'typeof ED'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(25,11): error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof DD'. + Property 'f' does not exist on type 'typeof DD'. +tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(26,11): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof DD'. + Property '42' does not exist on type 'typeof DD'. + + +==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts (6 errors) ==== + 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"] + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof D'. +!!! error TS7053: Property 'f' does not exist on type 'typeof D'. + const d = D[42] + ~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof D'. +!!! error TS7053: Property '42' does not exist on type 'typeof D'. + const e = ED["f"] + ~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof ED'. +!!! error TS7053: Property 'f' does not exist on type 'typeof ED'. + const f = ED[42] + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof ED'. +!!! error TS7053: Property '42' does not exist on type 'typeof ED'. + const g = DD["f"] + ~~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof DD'. +!!! error TS7053: Property 'f' does not exist on type 'typeof DD'. + const h = DD[42] + ~~~~~~ +!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof DD'. +!!! error TS7053: Property '42' does not exist on type 'typeof DD'. + \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature3.js b/tests/baselines/reference/staticIndexSignature3.js new file mode 100644 index 0000000000000..b146906a8ff3b --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature3.js @@ -0,0 +1,78 @@ +//// [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 (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + 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..b2f03588e4e4a --- /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 : any +>D["f"] : any +>D : typeof D +>"f" : "f" + +const d = D[42] +>d : any +>D[42] : any +>D : typeof D +>42 : 42 + +const e = ED["f"] +>e : any +>ED["f"] : any +>ED : typeof ED +>"f" : "f" + +const f = ED[42] +>f : any +>ED[42] : any +>ED : typeof ED +>42 : 42 + +const g = DD["f"] +>g : any +>DD["f"] : any +>DD : typeof DD +>"f" : "f" + +const h = DD[42] +>h : any +>DD[42] : any +>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..9e6e88cfb20a9 --- /dev/null +++ b/tests/baselines/reference/staticIndexSignature4.errors.txt @@ -0,0 +1,51 @@ +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 (4 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; + static [s: number]: 42 | 233; + } + + 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.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..d79848c9f29bd --- /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 : Pick +>B : typeof B + +type TFI = Pick +>TFI : Pick + +type TG = Omit +>TG : Pick +>B : typeof B + +type TGI = Omit +>TGI : Pick + diff --git a/tests/cases/compiler/staticIndexSignature1.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts similarity index 87% rename from tests/cases/compiler/staticIndexSignature1.ts rename to tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts index edc6575530feb..94e7e1f18e3bb 100644 --- a/tests/cases/compiler/staticIndexSignature1.ts +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature1.ts @@ -1,4 +1,3 @@ -// @skipLibCheck: true class C { static [s: string]: number; static [s: number]: 42 diff --git a/tests/cases/compiler/staticIndexSignature2.ts b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts similarity index 88% rename from tests/cases/compiler/staticIndexSignature2.ts rename to tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts index 3df6c1b48da44..67a8a5cea4dd4 100644 --- a/tests/cases/compiler/staticIndexSignature2.ts +++ b/tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature2.ts @@ -1,4 +1,3 @@ -// @skipLibCheck: true class C { static readonly [s: string]: number; static readonly [s: number]: 42 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 From d4624e6af98a2d46beb5bec539d040c99e96b1af Mon Sep 17 00:00:00 2001 From: kingwl Date: Wed, 20 May 2020 21:36:18 +0800 Subject: [PATCH 06/21] fix changes --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e118403e407c8..2cafef7b561d7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9974,7 +9974,7 @@ namespace ts { const declaration = getIndexDeclarationOfIndexSymbol(indexSymbol, indexKind); if (!declaration) return undefined; return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, - hasModifier(declaration, ModifierFlags.Readonly), declaration); + hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration); } function resolveReverseMappedTypeMembers(type: ReverseMappedType) { From a13190af8a4ce477f10abc2203a3270446bf2695 Mon Sep 17 00:00:00 2001 From: kingwl Date: Wed, 20 May 2020 21:51:50 +0800 Subject: [PATCH 07/21] Add more case --- .../staticIndexSignature6.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature6.ts 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 From 52884cc5b2185958d9be421962d633ff376bb34b Mon Sep 17 00:00:00 2001 From: kingwl Date: Wed, 20 May 2020 21:52:35 +0800 Subject: [PATCH 08/21] accept baseline --- .../reference/staticIndexSignature6.js | 36 +++++++++++ .../reference/staticIndexSignature6.symbols | 46 ++++++++++++++ .../reference/staticIndexSignature6.types | 61 +++++++++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 tests/baselines/reference/staticIndexSignature6.js create mode 100644 tests/baselines/reference/staticIndexSignature6.symbols create mode 100644 tests/baselines/reference/staticIndexSignature6.types 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 + From 56099855b27a1a4a56d73e10e8c76580498ae192 Mon Sep 17 00:00:00 2001 From: kingwl Date: Wed, 20 May 2020 22:16:33 +0800 Subject: [PATCH 09/21] fix error if extends others --- src/compiler/checker.ts | 15 ++++- .../staticIndexSignature3.errors.txt | 60 ------------------- .../reference/staticIndexSignature3.types | 24 ++++---- 3 files changed, 26 insertions(+), 73 deletions(-) delete mode 100644 tests/baselines/reference/staticIndexSignature3.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2cafef7b561d7..ed1b87829ff28 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3645,6 +3645,19 @@ namespace ts { return result || emptyArray; } + function getNamedOrIndexSignatureMembers(members: SymbolTable): Symbol[] { + const result = getNamedMembers(members); + const index = getIndexSymbolFromSymbolTable(members); + if (!index) { + return result; + } + if (!result.length) { + return [index]; + } + result.push(index); + return result; + } + function setStructuredTypeMembers(type: StructuredType, members: SymbolTable, callSignatures: readonly Signature[], constructSignatures: readonly Signature[], stringIndexInfo: IndexInfo | undefined, numberIndexInfo: IndexInfo | undefined): ResolvedType { (type).members = members; (type).properties = members === emptySymbols ? emptyArray : getNamedMembers(members); @@ -9923,7 +9936,7 @@ namespace ts { 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) { diff --git a/tests/baselines/reference/staticIndexSignature3.errors.txt b/tests/baselines/reference/staticIndexSignature3.errors.txt deleted file mode 100644 index b6fa831450b62..0000000000000 --- a/tests/baselines/reference/staticIndexSignature3.errors.txt +++ /dev/null @@ -1,60 +0,0 @@ -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(21,11): error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof D'. - Property 'f' does not exist on type 'typeof D'. -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(22,11): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof D'. - Property '42' does not exist on type 'typeof D'. -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(23,11): error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof ED'. - Property 'f' does not exist on type 'typeof ED'. -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(24,11): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof ED'. - Property '42' does not exist on type 'typeof ED'. -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(25,11): error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof DD'. - Property 'f' does not exist on type 'typeof DD'. -tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(26,11): error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof DD'. - Property '42' does not exist on type 'typeof DD'. - - -==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts (6 errors) ==== - 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"] - ~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof D'. -!!! error TS7053: Property 'f' does not exist on type 'typeof D'. - const d = D[42] - ~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof D'. -!!! error TS7053: Property '42' does not exist on type 'typeof D'. - const e = ED["f"] - ~~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof ED'. -!!! error TS7053: Property 'f' does not exist on type 'typeof ED'. - const f = ED[42] - ~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof ED'. -!!! error TS7053: Property '42' does not exist on type 'typeof ED'. - const g = DD["f"] - ~~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '"f"' can't be used to index type 'typeof DD'. -!!! error TS7053: Property 'f' does not exist on type 'typeof DD'. - const h = DD[42] - ~~~~~~ -!!! error TS7053: Element implicitly has an 'any' type because expression of type '42' can't be used to index type 'typeof DD'. -!!! error TS7053: Property '42' does not exist on type 'typeof DD'. - \ No newline at end of file diff --git a/tests/baselines/reference/staticIndexSignature3.types b/tests/baselines/reference/staticIndexSignature3.types index b2f03588e4e4a..1e063ec1d4acd 100644 --- a/tests/baselines/reference/staticIndexSignature3.types +++ b/tests/baselines/reference/staticIndexSignature3.types @@ -49,38 +49,38 @@ const b = B[42]; >42 : 42 const c = D["f"] ->c : any ->D["f"] : any +>c : number +>D["f"] : number >D : typeof D >"f" : "f" const d = D[42] ->d : any ->D[42] : any +>d : number +>D[42] : number >D : typeof D >42 : 42 const e = ED["f"] ->e : any ->ED["f"] : any +>e : boolean +>ED["f"] : boolean >ED : typeof ED >"f" : "f" const f = ED[42] ->f : any ->ED[42] : any +>f : 1 +>ED[42] : 1 >ED : typeof ED >42 : 42 const g = DD["f"] ->g : any ->DD["f"] : any +>g : 421 +>DD["f"] : 421 >DD : typeof DD >"f" : "f" const h = DD[42] ->h : any ->DD[42] : any +>h : 421 +>DD[42] : 421 >DD : typeof DD >42 : 42 From cf927fa2a7a202ee6e4c8cd2498f6b4675332a61 Mon Sep 17 00:00:00 2001 From: Wenlu Wang Date: Thu, 28 May 2020 09:57:55 +0800 Subject: [PATCH 10/21] Update vfsUtil.ts --- src/harness/vfsUtil.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/harness/vfsUtil.ts b/src/harness/vfsUtil.ts index c2dc94d781031..88fc73ebca9be 100644 --- a/src/harness/vfsUtil.ts +++ b/src/harness/vfsUtil.ts @@ -663,7 +663,7 @@ namespace vfs { if (!isFile(node)) throw createIOError("EBADF"); const buffer = this._getBuffer(node).slice(); - return encoding ? buffer.toString(encoding as any) : buffer; + return encoding ? buffer.toString(encoding) : buffer; } /** From 961f0692fb94a260cff45222534adb7bf3032236 Mon Sep 17 00:00:00 2001 From: kingwl Date: Thu, 28 May 2020 11:36:18 +0800 Subject: [PATCH 11/21] use equal to empty array --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ed1b87829ff28..a2f7434fdc2c4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3651,7 +3651,7 @@ namespace ts { if (!index) { return result; } - if (!result.length) { + if (result === emptyArray) { return [index]; } result.push(index); From 830872e3685b552f8d854d871aba0a72509329ed Mon Sep 17 00:00:00 2001 From: kingwl Date: Fri, 19 Jun 2020 17:20:47 +0800 Subject: [PATCH 12/21] static signature of interface is an error --- src/compiler/checker.ts | 2 +- .../staticIndexSignature4.errors.txt | 8 ++++- .../staticIndexSignature5.errors.txt | 32 +++++++++++++++++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 tests/baselines/reference/staticIndexSignature5.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c0076982d5d36..be427e0a62e15 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -37312,7 +37312,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 && modifier.kind !== SyntaxKind.StaticKeyword) { + 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/staticIndexSignature4.errors.txt b/tests/baselines/reference/staticIndexSignature4.errors.txt index 9e6e88cfb20a9..c452a1105d716 100644 --- a/tests/baselines/reference/staticIndexSignature4.errors.txt +++ b/tests/baselines/reference/staticIndexSignature4.errors.txt @@ -1,10 +1,12 @@ +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 (4 errors) ==== +==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts (6 errors) ==== class B { static readonly [s: string]: number; static readonly [s: number]: 42 | 233 @@ -17,7 +19,11 @@ tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature4.ts(26 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 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 From 0a8df61fe1dcea013b332905b6a8293e6fefab73 Mon Sep 17 00:00:00 2001 From: kingwl Date: Mon, 9 Nov 2020 16:01:25 +0800 Subject: [PATCH 13/21] Accept baseline --- tests/baselines/reference/staticIndexSignature3.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/baselines/reference/staticIndexSignature3.js b/tests/baselines/reference/staticIndexSignature3.js index b146906a8ff3b..be1d72f0c67c3 100644 --- a/tests/baselines/reference/staticIndexSignature3.js +++ b/tests/baselines/reference/staticIndexSignature3.js @@ -33,7 +33,7 @@ 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 (b.hasOwnProperty(p)) d[p] = b[p]; }; + 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) { From f327ed615547d238a28fd657c9c5d3878d4114d9 Mon Sep 17 00:00:00 2001 From: kingwl Date: Thu, 7 Jan 2021 17:14:55 +0800 Subject: [PATCH 14/21] Check index constraints for static signature --- src/compiler/checker.ts | 1 + .../staticIndexSignature7.errors.txt | 18 +++++++++++++ .../reference/staticIndexSignature7.js | 25 +++++++++++++++++++ .../reference/staticIndexSignature7.symbols | 20 +++++++++++++++ .../reference/staticIndexSignature7.types | 21 ++++++++++++++++ .../staticIndexSignature7.ts | 9 +++++++ 6 files changed, 94 insertions(+) create mode 100644 tests/baselines/reference/staticIndexSignature7.errors.txt create mode 100644 tests/baselines/reference/staticIndexSignature7.js create mode 100644 tests/baselines/reference/staticIndexSignature7.symbols create mode 100644 tests/baselines/reference/staticIndexSignature7.types create mode 100644 tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature7.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab0ed4355f50c..9a4f05a99aee3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35779,6 +35779,7 @@ namespace ts { if (produceDiagnostics) { checkIndexConstraints(type); + checkIndexConstraints(staticType); checkTypeForDuplicateIndexSignatures(node); checkPropertyInitialization(node); } 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/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 +} From 0ff15493c37456243a360ee3fe72e18440a3edbb Mon Sep 17 00:00:00 2001 From: kingwl Date: Thu, 7 Jan 2021 17:17:31 +0800 Subject: [PATCH 15/21] Accpet baseline --- tests/baselines/reference/staticIndexSignature3.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/baselines/reference/staticIndexSignature3.js b/tests/baselines/reference/staticIndexSignature3.js index be1d72f0c67c3..6ff912caf301a 100644 --- a/tests/baselines/reference/staticIndexSignature3.js +++ b/tests/baselines/reference/staticIndexSignature3.js @@ -37,6 +37,8 @@ var __extends = (this && this.__extends) || (function () { 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 __()); From efeaf942a29679407a779097425e9e63b98ce4b9 Mon Sep 17 00:00:00 2001 From: kingwl Date: Tue, 19 Jan 2021 22:11:27 +0800 Subject: [PATCH 16/21] Fix crash --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9a4f05a99aee3..bf3141e903b77 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12143,7 +12143,7 @@ namespace ts { } function getIndexSymbol(symbol: Symbol): Symbol | undefined { - return getIndexSymbolFromSymbolTable(symbol.members!); + return symbol.members ? getIndexSymbolFromSymbolTable(symbol.members) : undefined; } function getIndexSymbolFromSymbolTable(symbolTable: SymbolTable): Symbol | undefined { From 0ee41f6204c94751298e01262974a7cb8d89bbab Mon Sep 17 00:00:00 2001 From: kingwl Date: Wed, 20 Jan 2021 00:12:54 +0800 Subject: [PATCH 17/21] fix crash --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 11de0982f403d..d84cfeb3947eb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12215,8 +12215,8 @@ namespace ts { return symbolTable.get(InternalSymbolName.Index); } - function getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { - const indexSymbol = getIndexSymbol(symbol); + function getIndexDeclarationOfSymbol(symbol: Symbol | undefined, kind: IndexKind): IndexSignatureDeclaration | undefined { + const indexSymbol = symbol && getIndexSymbol(symbol); return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind); } From f91d84b27802b7b566e43f1ff763c906a63380e9 Mon Sep 17 00:00:00 2001 From: kingwl Date: Sun, 7 Feb 2021 16:17:20 +0800 Subject: [PATCH 18/21] Accept baseline --- tests/baselines/reference/staticIndexSignature5.types | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/staticIndexSignature5.types b/tests/baselines/reference/staticIndexSignature5.types index d79848c9f29bd..92360a7fde388 100644 --- a/tests/baselines/reference/staticIndexSignature5.types +++ b/tests/baselines/reference/staticIndexSignature5.types @@ -38,16 +38,16 @@ type TE = keyof typeof B; >B : typeof B type TF = Pick ->TF : Pick +>TF : TF >B : typeof B type TFI = Pick ->TFI : Pick +>TFI : TFI type TG = Omit ->TG : Pick +>TG : TG >B : typeof B type TGI = Omit ->TGI : Pick +>TGI : TGI From 246585f42314792834a25da873ae12046322bd43 Mon Sep 17 00:00:00 2001 From: kingwl Date: Thu, 4 Mar 2021 13:44:45 +0800 Subject: [PATCH 19/21] Fix regression --- src/compiler/checker.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c2a28f5f4ef01..d08d5a60c9742 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -10814,7 +10814,7 @@ namespace ts { } function getIndexInfoOfIndexSymbol(indexSymbol: Symbol, indexKind: IndexKind) { - const declaration = indexSymbol && getIndexDeclarationOfSymbol(indexSymbol, indexKind); + const declaration = getIndexDeclarationOfIndexSymbol(indexSymbol, indexKind); if (!declaration) return undefined; return createIndexInfo(declaration.type ? getTypeFromTypeNode(declaration.type) : anyType, hasEffectiveModifier(declaration, ModifierFlags.Readonly), declaration); @@ -12373,8 +12373,12 @@ namespace ts { } function getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { - const syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword; const indexSymbol = getIndexSymbol(symbol); + return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind); + } + + function getIndexDeclarationOfIndexSymbol(indexSymbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { + const syntaxKind = kind === IndexKind.Number ? SyntaxKind.NumberKeyword : SyntaxKind.StringKeyword; if (indexSymbol?.declarations) { for (const decl of indexSymbol.declarations) { const node = cast(decl, isIndexSignatureDeclaration); @@ -12386,6 +12390,7 @@ namespace ts { } } } + return undefined; } From 124e4614e33bec370968c932dfc7f3ba0e7a4321 Mon Sep 17 00:00:00 2001 From: kingwl Date: Thu, 4 Mar 2021 14:09:44 +0800 Subject: [PATCH 20/21] Fix crash --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d08d5a60c9742..cd9a7d2d570bc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12372,8 +12372,8 @@ namespace ts { return symbolTable.get(InternalSymbolName.Index); } - function getIndexDeclarationOfSymbol(symbol: Symbol, kind: IndexKind): IndexSignatureDeclaration | undefined { - const indexSymbol = getIndexSymbol(symbol); + function getIndexDeclarationOfSymbol(symbol: Symbol | undefined, kind: IndexKind): IndexSignatureDeclaration | undefined { + const indexSymbol = symbol && getIndexSymbol(symbol); return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind); } From f5508e1a4eb07bf10dc7df51e4e7700c676a3b8a Mon Sep 17 00:00:00 2001 From: kingwl Date: Thu, 25 Mar 2021 16:16:32 +0800 Subject: [PATCH 21/21] always return new array --- src/compiler/checker.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6b531c019b2d1..f286b1f58019a 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3890,14 +3890,7 @@ namespace ts { function getNamedOrIndexSignatureMembers(members: SymbolTable): Symbol[] { const result = getNamedMembers(members); const index = getIndexSymbolFromSymbolTable(members); - if (!index) { - return result; - } - if (result === emptyArray) { - return [index]; - } - result.push(index); - return result; + 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 {