SchemaFactory Class
Creates various types of schema for TreeNodes.
Signature
/** @sealed */
export declare class SchemaFactory<out TScope extends string | undefined = string | undefined, TName extends number | string = string>
Type Parameters
Parameter | Constraint | Default | Description |
---|---|---|---|
TScope | string | undefined | string | undefined | Scope added as a prefix to the name of every schema produced by this factory. |
TName | number | string | string | Type of names used to identify each schema produced in this factory. Typically this is just string but it is also possible to use string or number based enums if you prefer to identify your types that way. |
Remarks
For details related to inputting data constrained by schema (including via assignment), and how non-exact schema types are handled in general refer to Input. For information about recursive schema support, see methods postfixed with "recursive" and ValidateRecursiveSchema. To apply schema defined with this factory to a tree, see viewWith(config) and TreeViewConfiguration.
All schema produced by this factory get a unique identifier by combining the scope with the schema's Name
. The Name
part may be explicitly provided as a parameter, or inferred as a structural combination of the provided types. The APIs which use this second approach, structural naming, also deduplicate all equivalent calls. Therefor two calls to array(allowedTypes)
with the same allowedTypes will return the same TreeNodeSchema instance. On the other hand, two calls to array(name, allowedTypes)
will always return different TreeNodeSchema instances and it is an error to use both in the same tree (since their identifiers are not unique).
Note: POJO stands for Plain Old JavaScript Object. This means an object that works like a {}
style object literal. In this case it means the prototype is Object.prototype
and acts like a set of key value pairs (data, not methods). The usage below generalizes this to include array and map like objects as well.
There are two ways to use these APIs:
Customizable Approach:
-
Declaration:
class X extends schemaFactory.object("x", {}) {}
-
Allows adding "local" (non-persisted) members: Yes. Members (including methods) can be added to the class.
-
Prototype: The user-defined class.
-
Structurally named Schema: Not Supported.
-
Explicitly named Objects: Supported.
-
Explicitly named Maps and Arrays: Supported: Both declaration approaches can be used.
-
Node.js
assert.deepEqual
: Compares like class instances: equal to other nodes of the same type with the same content, including custom local fields. -
IntelliSense: Shows and links to user-defined class by name:
X
. -
Recursion: Supported with special declaration patterns.
POJO Emulation Approach:
-
Declaration:
const X = schemaFactory.object("x", {}); type X = NodeFromSchema<typeof X>;
-
Allows adding "local" (non-persisted) members: No. Attempting to set non-field members will result in an error.
-
Prototype:
Object.prototype
,Map.prototype
, orArray.prototype
depending on node kind. -
Structurally named Schema: Supported.
-
Explicitly named Objects: Supported.
-
Explicitly named Maps and Arrays: Not Supported.
-
Node.js
assert.deepEqual
: Compares like plain objects: equal to plain JavaScript objects with the same fields, and other nodes with the same fields, even if the types are different. -
IntelliSense: Shows internal type generation logic:
object & TreeNode & ObjectFromSchemaRecord<{}> & WithType<"test.x">
. -
Recursion: Unsupported: Generated
.d.ts
files replace recursive references withany
, breaking the use of recursive schema across compilation boundaries.
Note that while "POJO Emulation" nodes act a lot like POJO objects, they are not true POJO objects:
-
Adding new arbitrary fields will error, as well some cases of invalid edits.
-
They are implemented using proxies.
-
They have state that is not exposed via enumerable own properties, including a TreeNodeSchema. This makes libraries like node.js
assert.deepEqual
fail to detect differences in type. -
Assigning members has side effects (in this case editing the persisted/shared tree).
-
Not all operations implied by the prototype will work correctly: stick to the APIs explicitly declared in the TypeScript types.
Constructors
Constructor | Description |
---|---|
(constructor)(scope) | Construct a SchemaFactory with a given scope. |
Properties
Property | Modifiers | Type | Description |
---|---|---|---|
boolean | readonly |
TreeNodeSchemaNonClass<"com.fluidframework.leaf.boolean", NodeKind.Leaf, boolean, boolean, true, unknown, never> | TreeNodeSchema for holding a boolean. |
handle | readonly |
TreeNodeSchemaNonClass<"com.fluidframework.leaf.handle", NodeKind.Leaf, _dummyImport<unknown>, _dummyImport<unknown>, true, unknown, never> | TreeNodeSchema for holding an IFluidHandle. |
identifier | readonly |
FieldSchema<FieldKind.Identifier, typeof this.string> | A special field which holds a unique identifier for an object node. |
null | readonly |
TreeNodeSchemaNonClass<"com.fluidframework.leaf.null", NodeKind.Leaf, null, null, true, unknown, never> | TreeNodeSchema for JavaScript null . |
number | readonly |
TreeNodeSchemaNonClass<"com.fluidframework.leaf.number", NodeKind.Leaf, number, number, true, unknown, never> | TreeNodeSchema for holding a JavaScript number . |
scope | readonly |
TScope | Prefix appended to the identifiers of all TreeNodeSchema produced by this builder. |
string | readonly |
TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never> | TreeNodeSchema for holding a JavaScript string . |
Methods
Constructor Details
(constructor)
Construct a SchemaFactory with a given scope.
Signature
constructor(
scope: TScope);
Remarks
There are no restrictions on mixing schema from different schema factories. Typically each library will create one or more SchemaFactories and use them to define its schema.
Parameters
Parameter | Type | Description |
---|---|---|
scope | TScope |
Property Details
boolean
TreeNodeSchema for holding a boolean.
Signature
readonly boolean: TreeNodeSchemaNonClass<"com.fluidframework.leaf.boolean", NodeKind.Leaf, boolean, boolean, true, unknown, never>;
Type: TreeNodeSchemaNonClass<"com.fluidframework.leaf.boolean", NodeKind.Leaf, boolean, boolean, true, unknown, never>
handle
TreeNodeSchema for holding an IFluidHandle.
Signature
readonly handle: TreeNodeSchemaNonClass<"com.fluidframework.leaf.handle", NodeKind.Leaf, _dummyImport<unknown>, _dummyImport<unknown>, true, unknown, never>;
Type: TreeNodeSchemaNonClass<"com.fluidframework.leaf.handle", NodeKind.Leaf, _dummyImport<unknown>, _dummyImport<unknown>, true, unknown, never>
identifier
A special field which holds a unique identifier for an object node.
Signature
get identifier(): FieldSchema<FieldKind.Identifier, typeof this.string>;
Type: FieldSchema<FieldKind.Identifier, typeof this.string>
Remarks
The value of this field, a "node identifier", uniquely identifies a node among all other nodes in the tree. Node identifiers are strings, and can therefore be used as lookup keys in maps or written to a database. When the node is constructed, the identifier field does not need to be populated. The SharedTree will provide an identifier for the node automatically. An identifier provided automatically by the SharedTree has the following properties: - It is a UUID. - It is compressed to a space-efficient representation when stored in the document. - A compressed form of the identifier can be accessed at runtime via the Tree.shortId()
API. - It will error if read (and will not be present in the object's iterable properties) before the node has been inserted into the tree.
However, a user may alternatively supply their own string as the identifier if desired (for example, if importing identifiers from another system). In that case, it is up to the user to ensure that the identifier is unique within the current tree - no other node should have the same identifier at the same time. If the identifier is not unique, it may be read, but may cause libraries or features which operate over node identifiers to misbehave. User-supplied identifiers may be read immediately, even before insertion into the tree.
A node may have more than one identifier field (though note that this precludes the use of the Tree.shortId()
API).
null
TreeNodeSchema for JavaScript null
.
Signature
readonly null: TreeNodeSchemaNonClass<"com.fluidframework.leaf.null", NodeKind.Leaf, null, null, true, unknown, never>;
Type: TreeNodeSchemaNonClass<"com.fluidframework.leaf.null", NodeKind.Leaf, null, null, true, unknown, never>
Remarks
There are good [reasons to avoid using null](https://www.npmjs.com/package/%40rushstack/eslint-plugin\#rushstackno-new-null) in JavaScript, however sometimes it is desired. This TreeNodeSchema node provides the option to include nulls in trees when desired. Unless directly inter-operating with existing data using null, consider other approaches, like wrapping the value in an optional field, or using a more specifically named empty object node.
number
TreeNodeSchema for holding a JavaScript number
.
Signature
readonly number: TreeNodeSchemaNonClass<"com.fluidframework.leaf.number", NodeKind.Leaf, number, number, true, unknown, never>;
Type: TreeNodeSchemaNonClass<"com.fluidframework.leaf.number", NodeKind.Leaf, number, number, true, unknown, never>
Remarks
The number is a [double-precision 64-bit binary format IEEE 754](https://en.wikipedia.org/wiki/Double-precision\_floating-point\_format) value, however there are some exceptions: - NaN
, and the infinities are converted to null
(and may therefore only be used where null
is allowed by the schema). - -0
may be converted to 0
in some cases.
These limitations match the limitations of JSON.
scope
Prefix appended to the identifiers of all TreeNodeSchema produced by this builder.
Signature
readonly scope: TScope;
Type: TScope
Remarks
Generally each independently developed library (possibly a package, but could also be part of a package or multiple packages developed together) should get its own unique scope
. Then each schema in the library get a name which is unique within the library. The scope and name are joined (with a period) to form the schema identifier. Following this pattern allows a single application to depend on multiple libraries which define their own schema, and use them together in a single tree without risk of collisions. If a library logically contains sub-libraries with their own schema, they can be given a scope nested inside the parent scope, such as "ParentScope.ChildScope".
To avoid collisions between the scopes of libraries it is recommended that the libraries use Reverse domain name notation or a UUIDv4 for their scope. If this pattern is followed, application can safely use third party libraries without risk of the schema in them colliding.
You may opt out of using a scope by passing undefined
, but note that this increases the risk of collisions.
Usage
Example 1
Fluid Framework follows this pattern, placing the schema for the built in leaf types in the com.fluidframework.leaf
scope. If Fluid Framework publishes more schema in the future, they would be under some other com.fluidframework
scope. This ensures that any schema defined by any other library will not conflict with Fluid Framework's schema as long as the library uses the recommended patterns for how to scope its schema..
Example 2
A library could generate a random UUIDv4, like 242c4397-49ed-47e6-8dd0-d5c3bc31778b
and use that as the scope. Note: do not use this UUID: a new one must be randomly generated when needed to ensure collision resistance.
const factory = new SchemaFactory("242c4397-49ed-47e6-8dd0-d5c3bc31778b");
string
TreeNodeSchema for holding a JavaScript string
.
Signature
readonly string: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>;
Type: TreeNodeSchemaNonClass<"com.fluidframework.leaf.string", NodeKind.Leaf, string, string, true, unknown, never>
Remarks
Strings containing unpaired UTF-16 surrogate pair code units may not be handled correctly.
These limitations come from the use of UTF-8 encoding of the strings, which requires them to be valid unicode. JavaScript does not make this requirement for its strings so not all possible JavaScript strings are supported.
Method Details
array
Define a structurally typed TreeNodeSchema for a TreeArrayNode.
Signature
array<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Array<${string}>`>, NodeKind.Array, TreeArrayNode<T> & WithType<ScopedSchemaName<TScope, `Array<${string}>`>, NodeKind.Array>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, true, T, undefined>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
T | TreeNodeSchema | readonly TreeNodeSchema[] |
Remarks
The identifier for this Array is defined as a function of the provided types. It is still scoped to this SchemaFactory, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing. This does not support recursive types.
If using these structurally named arrays, other types in this schema builder should avoid names of the form Array<${string}>
.
Example
The returned schema should be used as a schema directly:
const MyArray = factory.array(factory.number);
type MyArray = NodeFromSchema<typeof MyArray>;
Or inline:
factory.object("Foo", {myArray: factory.array(factory.number)});
Parameters
Parameter | Type | Description |
---|---|---|
allowedTypes | T |
Returns
Return type: TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Array<${string}>`>, NodeKind.Array, TreeArrayNode<T> & WithType<ScopedSchemaName<TScope, `Array<${string}>`>, NodeKind.Array>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, true, T, undefined>
array
Define (and add to this library) a TreeNodeSchemaClass for a TreeArrayNode.
Signature
array<const Name extends TName, const T extends ImplicitAllowedTypes>(name: Name, allowedTypes: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Array, TreeArrayNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Array>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, true, T, undefined>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
Name | TName | |
T | ImplicitAllowedTypes |
Example
class NamedArray extends factory.array("name", factory.number) {}
Parameters
Parameter | Type | Description |
---|---|---|
name | Name | Unique identifier for this schema within this factory's scope. |
allowedTypes | T |
Returns
Return type: TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Array, TreeArrayNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Array>, Iterable<InsertableTreeNodeFromImplicitAllowedTypes<T>>, true, T, undefined>
arrayRecursive
SchemaFactory.array
except tweaked to work better for recursive types. Use with ValidateRecursiveSchema for improved type safety.
Signature
arrayRecursive<const Name extends TName, const T extends Unenforced<ImplicitAllowedTypes>>(name: Name, allowedTypes: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Array, TreeArrayNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Array, unknown>, {
[Symbol.iterator](): Iterator<InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>>;
}, false, T, undefined>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
Name | TName | |
T | Unenforced<ImplicitAllowedTypes> |
Remarks
This version of SchemaFactory.array
uses the same workarounds as objectRecursive(name, t). See ValidateRecursiveSchema for additional information about using recursive schema.
Parameters
Parameter | Type | Description |
---|---|---|
name | Name | |
allowedTypes | T |
Returns
Return type: TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Array, TreeArrayNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Array, unknown>, { [Symbol.iterator](): Iterator<InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>>; }, false, T, undefined>
map
Define a structurally typed TreeNodeSchema for a TreeMapNode.
Signature
map<const T extends TreeNodeSchema | readonly TreeNodeSchema[]>(allowedTypes: T): TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Map<${string}>`>, NodeKind.Map, TreeMapNode<T> & WithType<ScopedSchemaName<TScope, `Map<${string}>`>, NodeKind.Map>, MapNodeInsertableData<T>, true, T, undefined>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
T | TreeNodeSchema | readonly TreeNodeSchema[] |
Remarks
The unique identifier for this Map is defined as a function of the provided types. It is still scoped to this SchemaBuilder, but multiple calls with the same arguments will return the same schema object, providing somewhat structural typing. This does not support recursive types.
If using these structurally named maps, other types in this schema builder should avoid names of the form Map<${string}>
.
Example
The returned schema should be used as a schema directly:
const MyMap = factory.map(factory.number);
type MyMap = NodeFromSchema<typeof MyMap>;
Or inline:
factory.object("Foo", {myMap: factory.map(factory.number)});
Parameters
Parameter | Type | Description |
---|---|---|
allowedTypes | T |
Returns
Return type: TreeNodeSchemaNonClass<ScopedSchemaName<TScope, `Map<${string}>`>, NodeKind.Map, TreeMapNode<T> & WithType<ScopedSchemaName<TScope, `Map<${string}>`>, NodeKind.Map>, MapNodeInsertableData<T>, true, T, undefined>
map
Define a TreeNodeSchema for a TreeMapNode.
Signature
map<Name extends TName, const T extends ImplicitAllowedTypes>(name: Name, allowedTypes: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Map, TreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Map>, MapNodeInsertableData<T>, true, T, undefined>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
Name | TName | |
T | ImplicitAllowedTypes |
Example
class NamedMap extends factory.map("name", factory.number) {}
Parameters
Parameter | Type | Description |
---|---|---|
name | Name | Unique identifier for this schema within this factory's scope. |
allowedTypes | T |
Returns
Return type: TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Map, TreeMapNode<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Map>, MapNodeInsertableData<T>, true, T, undefined>
mapRecursive
SchemaFactory.map
except tweaked to work better for recursive types. Use with ValidateRecursiveSchema for improved type safety.
Signature
mapRecursive<Name extends TName, const T extends Unenforced<ImplicitAllowedTypes>>(name: Name, allowedTypes: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Map, TreeMapNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Map, unknown>, {
[Symbol.iterator](): Iterator<[
string,
InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>
]>;
} | {
readonly [x: string]: InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>;
}, false, T, undefined>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
Name | TName | |
T | Unenforced<ImplicitAllowedTypes> |
Remarks
This version of SchemaFactory.map
uses the same workarounds as objectRecursive(name, t). See ValidateRecursiveSchema for additional information about using recursive schema.
Parameters
Parameter | Type | Description |
---|---|---|
name | Name | |
allowedTypes | T |
Returns
Return type: TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Map, TreeMapNodeUnsafe<T> & WithType<ScopedSchemaName<TScope, Name>, NodeKind.Map, unknown>, { [Symbol.iterator](): Iterator<[ string, InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T> ]>; } | { readonly [x: string]: InsertableTreeNodeFromImplicitAllowedTypesUnsafe<T>; }, false, T, undefined>
object
Define a TreeNodeSchemaClass for a TreeObjectNode.
Signature
object<const Name extends TName, const T extends RestrictiveStringRecord<ImplicitFieldSchema>>(name: Name, fields: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
Name | TName | |
T | RestrictiveStringRecord<ImplicitFieldSchema> |
Parameters
Parameter | Type | Description |
---|---|---|
name | Name | Unique identifier for this schema within this factory's scope. |
fields | T | Schema for fields of the object node's schema. Defines what children can be placed under each key. |
Returns
Return type: TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNode<T, ScopedSchemaName<TScope, Name>>, object & InsertableObjectFromSchemaRecord<T>, true, T>
objectRecursive
object(name, fields) except tweaked to work better for recursive types. Use with ValidateRecursiveSchema for improved type safety.
Signature
objectRecursive<const Name extends TName, const T extends Unenforced<RestrictiveStringRecord<ImplicitFieldSchema>>>(name: Name, t: T): TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & { readonly [Property in keyof T as FieldHasDefaultUnsafe<T[Property]> extends false ? Property : never]: InsertableTreeFieldFromImplicitFieldUnsafe<T[Property], import("../../util/typeUtils.js").UnionToIntersection<T[Property]>>; } & { readonly [Property_1 in keyof T as FieldHasDefaultUnsafe<T[Property_1]> extends true ? Property_1 : never]?: InsertableTreeFieldFromImplicitFieldUnsafe<T[Property_1], import("../../util/typeUtils.js").UnionToIntersection<T[Property_1]>> | undefined; }, false, T>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
Name | TName | |
T | Unenforced<RestrictiveStringRecord<ImplicitFieldSchema>> |
Remarks
This version of object(name, fields) has fewer type constraints to work around TypeScript limitations, see Unenforced. See ValidateRecursiveSchema for additional information about using recursive schema.
Additionally ImplicitlyConstructable
is disabled (forcing use of constructor) to avoid error TS2589: Type instantiation is excessively deep and possibly infinite.
which otherwise gets reported at sometimes incorrect source locations that vary based on incremental builds.
Parameters
Parameter | Type | Description |
---|---|---|
name | Name | |
t | T |
Returns
Return type: TreeNodeSchemaClass<ScopedSchemaName<TScope, Name>, NodeKind.Object, TreeObjectNodeUnsafe<T, ScopedSchemaName<TScope, Name>>, object & { readonly [Property in keyof T as FieldHasDefaultUnsafe<T[Property]> extends false ? Property : never]: InsertableTreeFieldFromImplicitFieldUnsafe<T[Property], import("../../util/typeUtils.js").UnionToIntersection<T[Property]>>; } & { readonly [Property_1 in keyof T as FieldHasDefaultUnsafe<T[Property_1]> extends true ? Property_1 : never]?: InsertableTreeFieldFromImplicitFieldUnsafe<T[Property_1], import("../../util/typeUtils.js").UnionToIntersection<T[Property_1]>> | undefined; }, false, T>
optional
Make a field optional instead of the default, which is required.
Signature
optional<const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">): FieldSchema<FieldKind.Optional, T, TCustomMetadata>;
Type Parameters
Parameter | Constraint | Default | Description |
---|---|---|---|
T | ImplicitAllowedTypes | ||
TCustomMetadata | unknown | Custom metadata properties to associate with the field. See custom. |
Parameters
Parameter | Modifiers | Type | Description |
---|---|---|---|
t | T | The types allowed under the field. | |
props | optional | Omit<FieldProps<TCustomMetadata>, "defaultProvider"> | Optional properties to associate with the field. |
Returns
Return type: FieldSchema<FieldKind.Optional, T, TCustomMetadata>
optionalRecursive
optional(t, props) except tweaked to work better for recursive types. Use with ValidateRecursiveSchema for improved type safety.
Signature
optionalRecursive<const T extends Unenforced<ImplicitAllowedTypes>>(t: T, props?: Omit<FieldProps, "defaultProvider">): FieldSchemaUnsafe<FieldKind.Optional, T>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
T | Unenforced<ImplicitAllowedTypes> |
Remarks
This version of optional(t, props) has fewer type constraints to work around TypeScript limitations, see Unenforced. See ValidateRecursiveSchema for additional information about using recursive schema.
Parameters
Parameter | Modifiers | Type | Description |
---|---|---|---|
t | T | ||
props | optional | Omit<FieldProps, "defaultProvider"> |
Returns
Return type: FieldSchemaUnsafe<FieldKind.Optional, T>
required
Make a field explicitly required.
Signature
required<const T extends ImplicitAllowedTypes, const TCustomMetadata = unknown>(t: T, props?: Omit<FieldProps<TCustomMetadata>, "defaultProvider">): FieldSchema<FieldKind.Required, T, TCustomMetadata>;
Type Parameters
Parameter | Constraint | Default | Description |
---|---|---|---|
T | ImplicitAllowedTypes | ||
TCustomMetadata | unknown | Custom metadata properties to associate with the field. See custom. |
Remarks
Fields are required by default, but this API can be used to make the required nature explicit in the schema, and allows associating custom properties with the field.
Parameters
Parameter | Modifiers | Type | Description |
---|---|---|---|
t | T | The types allowed under the field. | |
props | optional | Omit<FieldProps<TCustomMetadata>, "defaultProvider"> | Optional properties to associate with the field. |
Returns
Return type: FieldSchema<FieldKind.Required, T, TCustomMetadata>
requiredRecursive
required(t, props) except tweaked to work better for recursive types. Use with ValidateRecursiveSchema for improved type safety.
Signature
requiredRecursive<const T extends Unenforced<ImplicitAllowedTypes>>(t: T, props?: Omit<FieldProps, "defaultProvider">): FieldSchemaUnsafe<FieldKind.Required, T>;
Type Parameters
Parameter | Constraint | Description |
---|---|---|
T | Unenforced<ImplicitAllowedTypes> |
Remarks
This version of required(t, props) has fewer type constraints to work around TypeScript limitations, see Unenforced. See ValidateRecursiveSchema for additional information about using recursive schema.
Parameters
Parameter | Modifiers | Type | Description |
---|---|---|---|
t | T | ||
props | optional | Omit<FieldProps, "defaultProvider"> |
Returns
Return type: FieldSchemaUnsafe<FieldKind.Required, T>