Skip to content

TS Conformance: model call/construct signatures on object type literals (not just interfaces) #122

@nickna

Description

@nickna

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

Context

#121 made { (x: number): void }, { new (x): T }, and mixed object types parse. But only the pure single call-signature case is modeled — it resolves to a TypeInfo.Function (TypeChecker.TypeParsing.cs:878). Anything richer is dropped:

  • mixed { (x: number): void; prop: string } — call signature discarded, only prop survives
  • overloaded { (x: number): string; (x: string): number }
  • construct signatures { new (x: number): T } — discarded entirely

TypeInfo.Interface already models these (CallSignatures / ConstructorSignatures, TypeInfo.cs:368-369); TypeInfo.Record does not (TypeInfo.cs:669-696). That asymmetry is the gap.

Scope / approach

  1. Add fields to TypeInfo.Record (TypeInfo.cs:669): List<CallSignature>? CallSignatures = null, List<ConstructorSignature>? ConstructorSignatures = null, plus HasCallSignature / IsCallable helpers mirroring Interface (TypeInfo.cs:374-377). Optional defaulted params → none of the 70 new TypeInfo.Record(...) sites break.
  2. Populate them in ParseInlineObjectTypeInfo (TypeChecker.TypeParsing.cs:781): the bare-signature members are already detected and skipped (~lines 799-823) — instead, parse the arrow-strings ((params) => ret, new (params) => ret) into TypeInfo.CallSignature / ConstructorSignature (TypeInfo.cs:320, :342) and attach to the Record. Keep the pure-single-call-sig → Function shortcut.
  3. Reuse existing compat helpers — no new assignability logic:
    • FunctionMatchesCallSignatures (Compatibility.Callable.cs:12) — wire Record.CallSignatures into the same path the interface uses at Compatibility.cs:704.
    • ClassMatchesConstructorSignatures (Compatibility.Callable.cs:54) for construct signatures.
    • Record↔Record / Record↔Interface signature compatibility.
  4. Make callable Records invocable at call sites (TypeChecker.Calls.cs:610): add a TypeInfo.Record { IsCallable: true } branch alongside the existing Interface / GenericInterface dispatch to CheckCallableInterfaceCall.

Acceptance

  • { (x:number): string; p: U } is both callable and structurally type-checked on p.
  • Overloaded call signatures resolve at call sites.
  • assignmentCompatWithCallSignatures* / assignmentCompatWithConstructSignatures* tests currently landing in Fail due to dropped modeling move toward Pass (regen baseline with SHARPTS_TSCONFORMANCE_UPDATE_BASELINE=1; no regressions).

Blast radius

Low. New Record fields are optional/defaulted (70 construction sites unaffected); compat helpers already exist. Main work is ParseInlineObjectTypeInfo population + one call-site branch.

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