Skip to main content

TypeScript

Both @fogpipe/forma-core and @fogpipe/forma-react ship with full type definitions. No @types/* packages needed.

Type Imports

imports.ts
// Core types
import type { Forma, FieldDefinition, FieldError } from "@fogpipe/forma-core";

// React component props
import type {
ComponentMap,
TextComponentProps,
NumberComponentProps,
SelectComponentProps,
DisplayComponentProps,
FormRendererHandle,
LayoutProps,
FieldWrapperProps,
PageWrapperProps,
} from "@fogpipe/forma-react";

Typed Components

Each field type has a corresponding props type. TypeScript errors if your component signature does not match:

components.tsx
import type {
TextComponentProps,
NumberComponentProps,
} from "@fogpipe/forma-react";

const TextInput = ({ field }: TextComponentProps) => (
<input
value={field.value ?? ""}
onChange={(e) => field.onChange(e.target.value)}
/>
);

const components: ComponentMap = {
text: TextInput,
email: TextInput,
// TypeScript errors if props don't match expected type
};

Validate Spec at Compile Time

Use satisfies to type-check a Forma spec literal without losing const narrowing:

spec.ts
const spec = {
version: "1.0",
meta: { id: "contact", title: "Contact" },
schema: { type: "object", properties: { name: { type: "string" } } },
fields: { name: { type: "text", label: "Name" } },
fieldOrder: ["name"],
} as const satisfies Forma;

Display Field Types

Display field components use DisplayComponentProps, which omits value and onChange:

display-field.ts
import type { DisplayComponentProps } from "@fogpipe/forma-react";

function DisplayField({ field }: DisplayComponentProps) {
field.content; // string | undefined
field.sourceValue; // unknown | undefined
field.format; // string | undefined
// field.value — not available (never)
// field.onChange — not available (never)
}

Field State Properties

All field props include state properties via BaseFieldProps:

field-state.ts
import type { TextComponentProps } from "@fogpipe/forma-react";

function TextInput({ field }: TextComponentProps) {
field.readonly; // boolean
field.prefix; // string | undefined
field.suffix; // string | undefined
field.variant; // string | undefined
field.variantConfig; // Record<string, unknown> | undefined
}

FormRenderer Ref

form-ref.ts
import type { FormRendererHandle } from "@fogpipe/forma-react";

const formRef = useRef<FormRendererHandle>(null);

formRef.current?.submitForm();
formRef.current?.focusFirstError();
const values = formRef.current?.getValues();

Event Types

event-types.ts
import type {
FormaEventMap,
FormaEvents,
FormaEventListener,
} from "@fogpipe/forma-react";

const listener: FormaEventListener<"fieldChanged"> = (event) => {
console.log(event.path, event.value);
};