Skip to content

TS Conformance: model class-body index signatures (currently parsed but discarded) #123

@nickna

Description

@nickna

Part of #80. Follow-up to #121.

Context

#121 made class A { [x: string]: T } parse, but TryConsumeClassIndexSignature (Parser.Classes.cs:516) discards the parsed value type — it returns only a bool. So the class type carries no index signature: it isn't structurally compatible with index-signature targets, and a["k"] isn't typed. The assignmentCompatWith{String,Numeric}Indexer* tests reach the checker but produce wrong results.

Scope / approach

  1. AST (AST.cs:381): add an IndexSignatures slot to Stmt.Class (reuse Stmt.IndexSignature, already used by interfaces).
  2. Parser (Parser.Classes.cs:516): change TryConsumeClassIndexSignature to return the parsed key-type + value-type (don't discard); collect into the new slot in ClassDeclaration (Parser.Classes.cs:506).
  3. ClassMetadataCore (ClassMetadataCore.cs:10): add StringIndexType / NumberIndexType / SymbolIndexType (optional defaulted). Update the 2 construction sites — MutableClass.FreezeCore (TypeInfo.cs:271) and generic substitution (Generics.MappedTypes.cs:179).
  4. Builder (TypeChecker.Statements.Classes.cs:12 CheckClassDeclaration): resolve the index-signature value types and thread them into the core, alongside field/method collection (~lines 224-264).
  5. Read sites — add TypeInfo.Class branches where index types are consulted (today only Record / Interface are handled):
    • structural excess-property / assignability: Compatibility.Structural.cs:53-85
    • index access & assignability: the ~8 sites in Properties.Index.cs (e.g. :153, :229, :240, :318, :420…).

Acceptance

  • class A { [x: string]: Base } is assignable to/from { [x: string]: Base } per TS rules.
  • Index access a["k"] on such a class is typed as the value type.
  • assignmentCompatWith{String,Numeric}Indexer* move out of Fail toward Pass (regen baseline; no regressions).

Blast radius

Medium. Positional-record changes to Stmt.Class and ClassMetadataCore (optional defaulted trailing params keep call sites compiling), but the ~10 index-read sites each need a new Class branch — mechanical but spread out. Best done as its own PR.

Sequencing

Independent of the call/signature follow-up; both build only on merged #121. That one is smaller/higher-leverage and should go first; this is meatier for a smaller (~6-test) cluster, so schedule as a standalone PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions