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);
};