Skip to content

Commit

Permalink
Cherry-pick PR #44129 into release-4.3 (#44240)
Browse files Browse the repository at this point in the history
Component commits:
7a9854c Ensure static index signatures have an errorNode available

626b431 Merge branch 'master' into error-node-static-index-signatures

a8327a0 Lookup static index signature declarations in the right symbol table, stop checking prototype props

Co-authored-by: Wesley Wigham <t-weswig@microsoft.com>
  • Loading branch information
TypeScript Bot and weswigham authored May 24, 2021
1 parent 27d6e44 commit d6e6fa7
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12531,6 +12531,11 @@ namespace ts {
return indexSymbol && getIndexDeclarationOfIndexSymbol(indexSymbol, kind);
}

function getIndexDeclarationOfSymbolTable(symbolTable: SymbolTable | undefined, kind: IndexKind): IndexSignatureDeclaration | undefined {
const indexSymbol = symbolTable && getIndexSymbolFromSymbolTable(symbolTable);
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) {
Expand Down Expand Up @@ -36773,15 +36778,16 @@ namespace ts {
}
}

function checkIndexConstraints(type: Type) {
const declaredNumberIndexer = getIndexDeclarationOfSymbol(type.symbol, IndexKind.Number);
const declaredStringIndexer = getIndexDeclarationOfSymbol(type.symbol, IndexKind.String);
function checkIndexConstraints(type: Type, isStatic?: boolean) {
const declaredNumberIndexer = getIndexDeclarationOfSymbolTable(isStatic ? type.symbol?.exports : type.symbol?.members, IndexKind.Number);
const declaredStringIndexer = getIndexDeclarationOfSymbolTable(isStatic ? type.symbol?.exports : type.symbol?.members, IndexKind.String);

const stringIndexType = getIndexTypeOfType(type, IndexKind.String);
const numberIndexType = getIndexTypeOfType(type, IndexKind.Number);

if (stringIndexType || numberIndexType) {
forEach(getPropertiesOfObjectType(type), prop => {
if (isStatic && prop.flags & SymbolFlags.Prototype) return;
const propType = getTypeOfSymbol(prop);
checkIndexConstraintForProperty(prop, propType, type, declaredStringIndexer, stringIndexType, IndexKind.String);
checkIndexConstraintForProperty(prop, propType, type, declaredNumberIndexer, numberIndexType, IndexKind.Number);
Expand Down Expand Up @@ -37160,7 +37166,7 @@ namespace ts {

if (produceDiagnostics) {
checkIndexConstraints(type);
checkIndexConstraints(staticType);
checkIndexConstraints(staticType, /*isStatic*/ true);
checkTypeForDuplicateIndexSignatures(node);
checkPropertyInitialization(node);
}
Expand Down
33 changes: 33 additions & 0 deletions tests/baselines/reference/staticIndexSignature3.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts(12,5): error TS2413: Numeric index type '1' is not assignable to string index type 'boolean'.


==== tests/cases/conformance/classes/staticIndexSignature/staticIndexSignature3.ts (1 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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2413: Numeric index type '1' is not assignable to string index type 'boolean'.
}

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]

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//// [staticIndexSignatureAndNormalIndexSignature.ts]
class Foo {
[p: string]: any;
static [p: string]: number;
}

//// [staticIndexSignatureAndNormalIndexSignature.js]
var Foo = /** @class */ (function () {
function Foo() {
}
return Foo;
}());
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=== tests/cases/compiler/staticIndexSignatureAndNormalIndexSignature.ts ===
class Foo {
>Foo : Symbol(Foo, Decl(staticIndexSignatureAndNormalIndexSignature.ts, 0, 0))

[p: string]: any;
>p : Symbol(p, Decl(staticIndexSignatureAndNormalIndexSignature.ts, 1, 5))

static [p: string]: number;
>p : Symbol(p, Decl(staticIndexSignatureAndNormalIndexSignature.ts, 2, 12))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
=== tests/cases/compiler/staticIndexSignatureAndNormalIndexSignature.ts ===
class Foo {
>Foo : Foo

[p: string]: any;
>p : string

static [p: string]: number;
>p : string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Foo {
[p: string]: any;
static [p: string]: number;
}

0 comments on commit d6e6fa7

Please sign in to comment.