@madenowhere/phaze-tsplugin
v0.0.2
Published
TypeScript language-service plugin that teaches the IDE about Phaze JSX `use:` directives — suppresses TS6133 'unused binding' diagnostics when the binding is consumed by a `use:X` JSX attribute.
Downloads
243
Maintainers
Readme
@madenowhere/phaze-tsplugin
TypeScript language-service plugin that teaches editors (VS Code, etc.) about Phaze JSX use:directive attributes — silences false-positive "unused binding" diagnostics when an import is consumed only via a use:NAME JSX attribute.
The problem
phaze-compile rewrites this:
<input use:autofocus={true} />into this (post-AST):
((__el) => (autofocus(__el, () => true), __el))(<input />)The rewritten code references autofocus like any other function call. But TypeScript's source-level analysis only sees the use:autofocus JSX namespaced attribute — which it doesn't count as a variable reference. With noUnusedLocals: true (or VS Code's "show unused" hints), the editor flags the import as unused even though it's the canonical consumer for the directive.
What this plugin does
Filters out TS6133 / TS6192 / TS6196 diagnostics whose unused name matches a binding consumed via a use:NAME JSX attribute somewhere in the same file. Other unused-binding warnings still fire — only the directive false-positive is suppressed.
Installation
pnpm add -D @madenowhere/phaze-tspluginThen add to your tsconfig.json:
{
"compilerOptions": {
"plugins": [{ "name": "@madenowhere/phaze-tsplugin" }]
}
}VS Code picks it up automatically via its bundled TypeScript server. Restart the TS server (Cmd+Shift+P → "TypeScript: Restart TS Server") after first install, then any time you change tsconfig plugins.
Limitations
- IDE only. TypeScript language-service plugins run inside the language server (editor flow). They do not affect
tscCLI behavior. If your CI runstsc --noEmitwithnoUnusedLocals: true, those checks will still flag directive imports. Workarounds: scopenoUnusedLocalsto source files only, or use eslint-based unused-imports checking with a Phaze-aware rule. - Per-file scope. The plugin scans only the source file the diagnostic is emitted in. If a directive import is in
a.tsand theuse:NAMEreference is inb.ts, the import ina.tswould still appear unused — which is correct (re-exporting through an unused intermediate file isn't a Phaze idiom). - Name-based matching. The plugin matches on the local binding name as it appears in TS's diagnostic message. Aliasing imports (
import { autofocus as _af }) means the JSX has to useuse:_afto match — TS still tracks the local name, so this works as expected.
