[API reference](https://evolu.dev/docs/api-reference) › [@evolu/common](https://evolu.dev/docs/api-reference/common) › [Type](https://evolu.dev/docs/api-reference/common/Type) › object

## Call Signature

```ts
function object<Props>(
  props: Props,
  ...validation: [ObjectValidationError<Props>] extends [never]
    ? []
    : [ValidationFailure<ObjectValidationError<Props>>]
): StrictObjectType<Props>;
```

Defined in: [packages/common/src/Type.ts:10474](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Type.ts#L10474)

Plain object [Type](https://evolu.dev/docs/api-reference/common/Type/interfaces/Type).

Use `object(props)` for objects with fixed property names. Properties are
required unless wrapped with [optional](https://evolu.dev/docs/api-reference/common/Type/functions/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](https://evolu.dev/docs/api-reference/common/Type/functions/record) with the predefined [String](https://evolu.dev/docs/api-reference/common/Type/variables/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](https://evolu.dev/docs/api-reference/common/Object/functions/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](https://evolu.dev/docs/api-reference/common/Type/functions/instanceOf) for class
Outputs or [transform](https://evolu.dev/docs/api-reference/common/Type/functions/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

```ts
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:

```ts

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.

```ts
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

```ts
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](https://github.com/evoluhq/evolu/blob/037c390af081e9944d616ff298a729515c5c5ab7/packages/common/src/Type.ts#L10511)

Creates an Object Type with additional record properties.

### Example

```ts

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"]>();
```