FormNodeValue
FormNodeValue<typeof node> extracts the committed value type of any form(), group(),
array(), or field() instance. Use it to type saved drafts, service parameters, or other values
that should follow a node's inferred model.
import type { FormNodeValue } from '@ngblocks/form-nodes';
type MyFormValue = FormNodeValue<typeof myForm>;
🌳 Infer form and child values
import { array, field, form, type FormNodeValue } from '@ngblocks/form-nodes';
const profile = form({
name: field('Marco'),
country: field.strict<string>('Switzerland'),
address: { city: field('Zurich') },
contacts: array({
email: field(''),
}, {
initialValue: [{ email: 'marco@example.com' }],
}),
});
type ProfileValue = FormNodeValue<typeof profile>;
// {
// name: string;
// country: string;
// address: { city: string };
// contacts: { email: string }[];
// }
type NameValue = FormNodeValue<typeof profile.name>; // string
type AddressValue = FormNodeValue<typeof profile.address>; // { city: string }
type ContactsValue = FormNodeValue<typeof profile.contacts>; // { email: string }[]
const name: NameValue = 'Ada';
const address: AddressValue = { city: 'Bern' };
const contacts: ContactsValue = [{ email: 'marco@example.com' }];
const draft: ProfileValue = {
name,
country: 'Switzerland',
address,
contacts,
};
profile.set(draft);
The same helper works for the complete form and each selected child. It preserves each node's value type recursively:
- Fields retain their inferred or declared nullability;
field.nullable()explicitly includes null. - Explicit
undefined, literal unions, and application-specific object types are preserved. - Groups and nested forms produce nested objects.
- Dynamic arrays produce arrays of their item values. An array-valued field retains its own field type, including nullability of the complete array.
- Nodes created with
createFormPrimitives()preserve their configured nullability defaults and any explicit field overrides.
📐 Signature and scope
type FormNodeValue<TNode extends AnyNode> = ReturnType<TNode>;
Pass the type of an existing node instance. Standalone nodes, nested nodes, and array items are
all supported. Definition objects and ordinary functions are not node instances.
When an array item may be missing, narrow out undefined or use NonNullable on its type first.
The result is equivalent to ReturnType<typeof node> and describes what calling node()
returns. It also works when children are named value, api, or nodeType, since those names do
not change the node's call signature.
The helper follows the static declaration. Adding a child with add() later does not widen the
original form or group type; use the returned child for its exact inferred type.
This is a type-only export. It does not read the node, create a subscription, validate a value, or change runtime behavior.
🔗 Related value types
| Type | Input | Purpose |
|---|---|---|
FormNodeValue<typeof node> | Any node instance type | Extract its committed value type. |
FormValue<TNodes> | A map of child-node types | Map each child node to its value type. |
FormValueContract<Model> | An existing object value model | Check an inferred form or group with satisfies. |
Use FormNodeValue when the node declaration defines your model. Use
FormValueContract when an existing domain model should constrain
the form declaration.
🔗 Related reference
form()describes declarations, options, and value operations.field(),group(), andarray()describe the other supported primitives.FormValueContractchecks an existing value model.createFormPrimitives()configures field nullability defaults.