mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-01 07:33:12 +08:00
In a JavaScript file, `const m = new Map()`, `new Set()` and `[]` type as Map<any, any>, Set<any> and any[], so every use lowered to the checked-dynamic collection operations: boxed keys and values, generic method dispatch, and dynamic arithmetic on what they returned. js-collection-types.ts proves types for such bindings from their uses. A `const` qualifies when every reference is a direct use of the collection: - for a Map: get/has/delete/clear, size, and set as a statement; - for a Set: has/delete/clear, size, and add as a statement; - for an array: push/pop/shift/at/includes/indexOf/join and length. The value then never leaves the binding. Its key, value or element type is the one primitive (string, number or boolean) of every expression the program writes. That is found by a fixed point that types `m.get(k) ?? d`, arithmetic, comparisons and constants defined from them, and it requires lookups of the same type. Any other reference (passing, returning, storing, exporting, iterating, inspecting, an optional call), a direct `eval` in the file, or any doubt keeps the binding untyped. A proven binding answers the lowerer's typeOf with a carrier type declared in scriptc-overrides.d.ts, which only the lowering program includes. `new Map()` and `new Set()` adopt it, so the binding lowers as the typed Map<K, V>, Set<K> or T[], as a JSDoc @type would make it. 7985 covers the typed cases and every refusal.