You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: [#1380] surface implicit Object methods on interop record types (#1382)
closes#1380
## Summary
TypeScript implicitly extends every interface from `Object`, which
declares `toString()`, `toLocaleString()`, and `valueOf()`. Floe's
interop loader only collected the members written in each interface
body, so `url.toString()` failed with `E021` even though the WHATWG /
`@types/node` URL interface relies on `Object` inheritance for that
method. Same gap affected `Date.toString`, `Date.toLocaleString`,
`Error.toString`, etc.
The fix:
- `wrap_boundary_type` now appends those three methods (when not already
present) to every Record produced from the interop boundary — single
source of truth in `IMPLICIT_OBJECT_METHOD_NAMES`
(`crates/floe-core/src/interop/wrapper.rs`).
- The same helper runs on the hand-crafted `Response`/`Error`/`Event`
records in the checker (`crates/floe-core/src/checker.rs`).
- `records_compatible` (`crates/floe-core/src/checker/type_compat.rs`)
skips the implicit names on both sides of structural assignability, so
plain Floe records are still assignable to wrapped param shapes — every
JS object inherits these, so it would be wrong to require source records
to declare them.
User-defined Floe records (`type User = { ... }`) bypass
`wrap_boundary_type`, so they still reject `.toString()` with E021 —
only interop-boundary records gain the implicit methods.
## Test plan
- [x]
`crates/floe-core/src/checker/tests.rs::ambient_record_exposes_to_string`
— `url.toString()` typechecks against an ambient URL with only `href`
declared
- [x]
`crates/floe-core/src/checker/tests.rs::implicit_object_methods_do_not_block_assignment`
— plain Floe record still assignable to wrapped foreign param
- [x]
`crates/floe-core/src/interop/tests.rs::explicit_to_string_overrides_implicit`
— user-declared `toString(): number` keeps its signature
- [x] Existing `wrap_*` tests updated via `record_with_object_methods`
helper
- [x] Quality gate on examples: `floe fmt` + `floe check` + `floe build`
on `examples/todo-app/` and `examples/store/` — all pass
- [x] `cargo test --release -p floe-core --lib` — 1615 passed
- [x] `cargo clippy --all-targets --release -- -D warnings` — clean
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments