---
title: TypeScript
description: Use Moraine component props, namespace types, values, items, and callback contexts safely.
sidebar:
  order: 3
search:
  tags: [types, namespaces, generics, props]
---

# TypeScript

> Use Moraine component props, namespace types, values, items, and callback contexts safely.

## Overview

Moraine exposes types in two layers:

- **`XxxProps`** — the top-level public props type for each component, exported directly from `moraine`.
- **`XxxT.*`** — a namespace of component-specific sub-types (items, values, slots, etc.), also exported from `moraine`.

```tsx
import type { ButtonProps, SelectProps, SelectT } from 'moraine'
```

## Component Props (`XxxProps`)

Every component exports a `Props` type named after the component (e.g. `ButtonProps`, `SelectProps`). Use this when wrapping a component or extending its props interface.

```tsx
import type { ButtonProps } from 'moraine'

interface PrimaryButtonProps extends ButtonProps {
  trackingId?: string
}

function PrimaryButton(props: PrimaryButtonProps) {
  // ...
}
```

## Root props

Every public component owns a documented root element. In the default type mode, that root accepts arbitrary attributes, while component business props stay separate from the DOM surface and `ref` remains typed to the concrete root element.

```tsx
<Card aria-describedby="details" data-testid="card" />
```

Full intrinsic attributes are opt-in because including every HTML attribute in every component makes editor completion slower and allows control props to be mistaken for wrapper props. Enable the expanded surface with a type-only package-root augmentation:

```tsx
declare module 'moraine' {
  interface MoraineTypeConfig {
    enableRootAutocomplete: true
  }
}
```

The augmentation has no runtime effect. It enables the exact attributes for the documented root tag, including camelCase Solid handlers, and preserves required props for custom Solid components passed through polymorphic `as` APIs such as `Button`, `List`, `FormField`, and `FileUpload`. Lowercase event aliases and Solid directive prefixes remain excluded from the autocomplete surface.

Root attributes are forwarded at runtime even when the expanded type mode is disabled. Generated state metadata is emitted before user rest props, so caller values override `data-slot`, state `data-*`, and generated `aria-*` attributes. Wrapper components forward root props to their wrapper or trigger, while form control props and secondary APIs such as `listboxProps` stay on their documented internal elements.

## Component Namespace (`XxxT`)

The `XxxT` namespace groups all supporting types for a component under a single import. This keeps the top-level exports focused and avoids polluting the global type space.

### Item models

List-like components (e.g. `Select`, `MultiSelect`) expose an `Item` type for their option objects.

```tsx
import type { SelectT } from 'moraine'

const regionOptions: SelectT.Item[] = [
  { label: 'Asia', value: 'asia' },
  { label: 'Europe', value: 'europe' },
]
```

### Controlled values

Use `XxxT.Value` to type state variables that hold a component's selected or active value.

```tsx
import type { SelectT } from 'moraine'

let selected: SelectT.Value | null = null
```

### Render callback params

Prop callbacks often receive component-specific objects. Type them using the appropriate namespace member.

```tsx
import type { SelectProps } from 'moraine'

const labelRender: SelectProps['labelRender'] = (option) =>
  typeof option.label === 'string' ? option.label : (option.key ?? 'Unknown')
```

### Slot types

`XxxT.Slot` is an object whose keys are valid slot names used by the `classes` and `styles` props. Each key can carry JSDoc describing the slot and its styling attributes.

```tsx
import type { CardT } from 'moraine'

const overrides: CardT.Classes = {
  header: 'bg-gray-100',
}
```

## Namespace Reference

Each `XxxT` namespace may expose the following members depending on the component:

| Member    | Description                                               |
| --------- | --------------------------------------------------------- |
| `Slot`    | Object keyed by slot names used by `classes` and `styles` |
| `Variant` | Variant options for visual/style customization            |
| `Item`    | Data model for list items or option objects               |
| `Value`   | Domain type of the component's controlled value           |
| `Classes` | Typed map from slot name to CSS class string              |
| `Styles`  | Typed map from slot name to inline style object           |
| `Base`    | Component-specific business props (internal)              |
| `Props`   | Final public props shape (same as `XxxProps`)             |

## Tips

- Use `import type` for all type-only imports to keep runtime bundles clean.
- Prefer exported `XxxProps` and `XxxT.*` types over importing internal source types directly.
- When in doubt, start with `XxxProps`; reach for `XxxT.*` only when you need a more specific sub-type.

