v0.20.230 - 19.9 / 8.6

TypeScript

pota ships a set of ambient component-utility types in pota/typescript/jsx/components.d.ts. Once your tsconfig has "jsxImportSource": "pota", these types are globally available — no import line needed.

# Utility types at a glance

nameshapewhat it's for
Component<P>(props: P) => JSX.Elementany function component taking props P
ParentComponent<P>Component<P & { children? }>component that accepts children — the typical layout/wrapper component
VoidComponent<P>Component<P>component that explicitly does not accept children
FlowComponent<P, C>Component<P & { children?: C }>flow-control component (Show, For, Switch) where C is a render-callback type
ComponentType<P>Component<P> | (new (props: P) => JSX.ElementClass)anything that can be rendered as a component — function or class
Children<C>C | (C | JSX.Element)[]mixed list of render callbacks and elements — useful for callback-style children (Show, For)
ComponentProps<T>props of a component function or intrinsic tagextracts props from a component reference or tag name ('button', typeof MyButton)

# Typing props

The simplest component is a function that receives a typed props object. You don't need any of the utility types for this — an inline object type is enough. Any prop you omit with a default is still available to callers.

# Component

Component<P> is an alias for (props: P) => JSX.Element. Reach for it when you want the component's type to be visible at the declaration (useful for reassignment, overriding defaultProps patterns, or handing the component to a higher-order function). The annotation also forces the return type to be a JSX element, which catches accidental void returns early.

# ParentComponent

A parent component is one that renders children inside itself — cards, layouts, providers. ParentComponent<P> adds a children?: JSX.Element prop on top of P so you don't have to type it yourself. Callers get autocomplete for children without the component author having to reach for JSX.Element explicitly.

# VoidComponent

The opposite of ParentComponent: VoidComponent<P> is a component that must not be passed children. Useful for self-closing leaf elements like icons, avatars, or form primitives — catching stray children at compile time prevents bugs where passed content would be silently ignored.

# FlowComponent

Flow-control components receive children as a function (or array of functions) that are invoked with a value — the pattern <Show/>, <For/>, <Switch/> use internally. FlowComponent<P, C> lets you type the callback shape explicitly, so callers get parameter inference on their render function and can't pass plain JSX where a callback is expected.

# ComponentType

ComponentType<P> is the union of a function component and a component class — anything pota knows how to render. Use it for generic code that works with either flavour: higher-order components, or prop types that take "a component" without caring which kind.

# Children

Children<C> widens a single callback type C into "either one C, or a mixed array of C and plain JSX elements". It's the shape <Show/> and <Switch/> accept for their children, so users can interleave render callbacks with straightforward JSX without extra wrappers.

# ComponentProps

ComponentProps<T> pulls the props type out of any function component (typeof Foo) or intrinsic tag ('button', 'a', …). It's how you build a wrapper that forwards every prop the wrapped thing accepts, without having to maintain a parallel prop list as the underlying type changes.

# Disallowing a prop

Wrap the underlying props with Omit<T, K> when you want the wrapper to control a particular prop itself. Callers that try to pass the omitted key get a compile error, making the intended usage visible at the type level.

# Requiring a prop

Most DOM props are optional by default. To force one required, subtract it with Omit and add it back through Required<Pick<…>>. Handy for accessibility-critical props like an <img>'s alt text.

# use:* plugin props

Plugins registered with propsPlugin add a new prop every element accepts. Tell TypeScript about it by merging into JSX.ElementAttributes<Element>inside a declare module 'pota' block. The Element generic is threaded through by pota so callback props can be typed against the element they're attached to (e.g. (node: Element) => void for a ref-style callback).

For a prop that accepts both a plain value and a signal, widen the type with | (() => T) — same pattern as intrinsic attributes.

# Custom Element

Declaring a custom element in TypeScript has two parts: tell the compiler the tag exists, and describe its attributes. You do that by merging into JSX.IntrinsicElements with a declare module 'pota' block. To allow a signal as an attribute value, widen the type with () => T — that matches pota's runtime acceptance of function values.