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
| name | shape | what it's for |
|---|---|---|
| Component<P> | (props: P) => JSX.Element | any 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 tag | extracts 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.