Files
scriptc/tests/fixtures/npm-static/node_modules/declared-members
Malte UblandClaude Opus 5.5 177b2fde49 Cross package values at their declared type where the JS literal type lacks members
An opted-in package's JavaScript types its own values. The lowering types
a consumer's view of such a value from that JavaScript, and the
declaration boundary (decl-projection.ts) casts to the declared type only
where the JavaScript world answers `any`. A function that returns an
object literal has a precise JavaScript type, so it never crossed, even
where that literal type lacks members the declarations promise:

- `{ [key: string]: string }` over `{ size: "12px" }`: the consumer read
  `settings["font"] ?? "x"` through the literal's fixed key set. The
  checker types the miss `any` (a JavaScript literal), but the keyed read
  took the declared fields' common type, so the miss trapped with
  "record has no key" and aborted the process.
- an expando `out.max = ...` on a non-empty literal, which the JavaScript
  checker leaves out of the literal's type: reading `stats(xs).max` was
  refused with SC1090.

A package value whose JavaScript type is an object literal that lacks a
declared property or string index signature now crosses at its declared
type, so missing keys read undefined through the index signature and
expando members are read from the object. An index signature whose values
do not project (a package interface) keeps the value untyped (`as any`),
so its reads are the JavaScript reads. Only programs compiled with
--npm-static whose consumers read such values are rewritten.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 11:51:24 -07:00
..