API reference › @evolu/common › Type › object
Call Signature
function object<Props>(
props: Props,
...validation: [ObjectValidationError<Props>] extends [never]
? []
: [ValidationFailure<ObjectValidationError<Props>>]
): StrictObjectType<Props>;
Defined in: packages/common/src/Type.ts:10474
Plain object Type.
Use object(props) for objects with fixed property names. Properties are
required unless wrapped with optional. An optional property may be
absent, but a present value is still validated and does not implicitly accept
undefined.
Without a second argument, fromUnknown rejects additional properties. Pass
a record with the predefined String key Type to validate and
preserve additional string-keyed properties.
fromUnknown requires a plain object. Plain object Types model only own
enumerable data properties, so Object prototype properties neither satisfy
required properties nor make optional properties present. This keeps Outputs
valid after ordinary object spread restores Object.prototype.
The prototype must satisfy the realm-neutral structural heuristic described by isPlainObject. A matching custom root prototype can be classified as plain; other custom prototypes, class instances, accessors, and non-enumerable properties are rejected. Use instanceOf for class Outputs or transform to decode instances into plain data.
When decoding changes no property, it preserves the input. When decoding or
encoding changes a property, it constructs an object with a null
prototype.
By default, validation returns the first property issue. Pass { errors: "all" } to collect all issues.
Example
import {
assertOk,
assertType,
Int64FromInt64String,
String,
object,
type InferType,
} from "@evolu/common";
const User = object({
name: String,
loginCount: Int64FromInt64String,
});
interface User extends InferType<typeof User> {}
// Validate an unknown value.
const userFromUnknown = User.fromUnknown({
name: "Ada",
loginCount: "42",
});
assertOk(userFromUnknown, { name: "Ada", loginCount: 42n });
// Validate the object and root property Types.
const userInput = User.parent.fromUnknown({
name: "Ada",
loginCount: "42",
});
assertOk(userInput, { name: "Ada", loginCount: "42" });
// Run the remaining property stages.
const userFromInput = User.from.parent(userInput.value);
assertOk(userFromInput, { name: "Ada", loginCount: 42n });
assertType<typeof User.Output, typeof userFromInput.value>();
Note that TypeScript does not model an object's runtime prototype. This can
make a plain TypeScript object interpret an inherited Object.prototype name
as an object property:
import { assertEqual, assertErr, assertTrue, trySync } from "@evolu/common";
interface Values {
readonly toString?: number;
}
const nullPrototypeValues = Object.create(null) as Values;
const values = { ...nullPrototypeValues };
// TypeScript treats the inherited function as `number | undefined`.
const value: number | undefined = values.toString;
const valueType = typeof value;
assertEqual(valueType, "function");
const called = trySync(
() => {
if (value !== undefined) value.toFixed(0);
},
(error) => error,
);
assertErr(called);
assertTrue(called.error instanceof TypeError);
Evolu Object Outputs use the same TypeScript object representation.
import {
assertEqual,
assertErr,
assertOk,
assertTrue,
trySync,
Number,
object,
optional,
type Data,
} from "@evolu/common";
const Values = object({ toString: optional(Number) });
const result = Values.fromUnknown({});
const emptyValues: Data = {};
assertOk(result, emptyValues);
const value: number | undefined = result.value.toString;
const valueType = typeof value;
assertEqual(valueType, "function");
const called = trySync(
() => {
if (value !== undefined) value.toFixed(0);
},
(error) => error,
);
assertErr(called);
assertTrue(called.error instanceof TypeError);
In other words, treat Object Outputs as data rather than calling inherited object methods through them.
Call Signature
function object<Props, Rest>(
props: Props,
record: Rest,
...validation: [
ObjectValidationError<Props> | ObjectRecordValidationError<Props, Rest>,
] extends [never]
? []
: [
ValidationFailure<
| ObjectValidationError<Props>
| ObjectRecordValidationError<Props, Rest>
>,
]
): ObjectWithRecordType<
Props,
Rest extends ObjectRecordTypeNode ? Rest : never
>;
Defined in: packages/common/src/Type.ts:10511
Creates an Object Type with additional record properties.
Example
import { assertOk, assertType, String, object, record } from "@evolu/common";
const RequestHeaders = object(
{ authorization: String },
record(String, String),
);
const result = RequestHeaders.fromUnknown({
authorization: "Bearer token",
"x-request-id": "request-1",
});
assertOk(result, {
authorization: "Bearer token",
"x-request-id": "request-1",
});
assertType<string | undefined, (typeof result.value)["x-request-id"]>();