[]previous and next page

TypeScript

The compiler transforms JSX, so TypeScript only type-checks.

For agentsUpdated

The compiler transforms JSX, so TypeScript only type-checks. Three things in tsconfig.json matter for ShadowJS; the rest is a strict, Vite-friendly baseline (this is what create-shadow-app writes).

json
{
  "compilerOptions": {
    "target": "ES2022",
    "lib": ["ES2023", "DOM", "DOM.Iterable"],
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "jsx": "preserve",
    "jsxImportSource": "@shadow-js/web",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "verbatimModuleSyntax": true,
    "isolatedModules": true,
    "noEmit": true,
    "skipLibCheck": true,
    "types": ["vite/client"]
  },
  "include": ["src", "vite.config.ts"]
}
Setting Value Why
jsxImportSource "@shadow-js/web" Required. TypeScript reads the JSX namespace from @shadow-js/web/jsx-runtime: element and attribute types for HTML, SVG and MathML, typed event handlers, JSX.Element.
jsx "preserve" Leaves JSX alone. "react-jsx" also type-checks, because both resolve the same module; nothing is emitted either way (noEmit).
moduleResolution "Bundler" Resolves the packages' exports maps, including the types condition.
verbatimModuleSyntax, isolatedModules true Vite transpiles each file on its own. Import types with import type.
types ["vite/client"] Declares import.meta.env and asset imports.
strict, noUncheckedIndexedAccess true Recommended. useStore arrays and Record lookups give T | undefined with the second one.

The JSX types are extensible. Declaration-merge the CustomEvents interface to type on: listeners and the Directives interface to type use: directives:

src/jsx-augmentation.tsts
declare module "@shadow-js/web/jsx-runtime" {
  interface CustomEvents {
    toast: CustomEvent<{ message: string }>;
  }
  interface Directives {
    tooltip: string;
  }
}

export {};
src/Notice.tsxtsx
import "./jsx-augmentation";

export function Notice() {
  return (
    <div on:toast={(event) => event.detail.message} use:tooltip="Dismiss">
      notice
    </div>
  );
}