-`#writeAttrs` wraps every named attribute key in quotes (`.write('"').anchor(defaultMapPosition).copy(name).write('"')` at l.1052, 1063, 1166, 1224), and TypeScript computes an excess-property spelling suggestion only when the key node is an identifier, so every identifier-safe attribute typo loses its "Did you mean…?". `<input onKeydown(e) {}/>` extracts as `"onKeydown"(e){}`, and `mtc` (`packages/type-check`) and the LSP report the bare TS2353 "Object literal may only specify known properties, and '\"onKeydown\"' does not exist in type 'Directives & Input'", where the identical object with an identifier key reports TS2561 "…Did you mean to write 'onKeyDown'?". That reads as "this element takes no event handlers" rather than "you miscased one" — and upstream the runtime binds it fine (marko's `getEventHandlerName` lowercases everything after `on`, so only marko's `tags-html.d.ts` insists on exact camelCase), which is exactly why the type layer's message should name the right spelling. Quoting is required for names that are not valid identifiers (`on-click`, `data-x`, `class:foo`), so gate it: reuse the existing `REG_OBJECT_PROPERTY` (l.52) and `copy(name)` unquoted when it matches, keeping the `anchor(defaultMapPosition)` mapping for the default-attr case; snapshots barely move because prettier already prints these keys unquoted. Distinct from the `#writeTag` "cannot resolve tag" entry above — that is a missing diagnostic, this is a present diagnostic missing its suggestion. Re-verify by adding `<input onKeydown(e) {}/>` as `packages/language-server/src/__tests__/fixtures/script/attr-name-typo/index.marko`, running `pnpm run test:server`, and reading the `## Diagnostics` block of the generated `__snapshots__/attr-name-typo.expected/index.md`.
0 commit comments