Skip to content

object()

ts
function object<T>(schema): Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>

Objects have a fixed set of properties of different types. If the data received has properties that are not declared in the parser, the extra properties are omitted from the result.

See

objectStrict for a strict version.

Type Parameters

Type Parameter
T extends Record<string, unknown>

Parameters

ParameterTypeDescription
schema{ [K in string | number | symbol]-?: Object extends Pick<T, K> ? OptionalParser<T[K]> : Parser<T[K]> }maps keys to validation functions.

Returns

Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>

a parser function that validates objects according to schema.

Examples

Object with both required and optional properties:

ts
const parseUser = object({
  id: parseNumber,
  active: parseBoolean,
  name: parseString,
  email: optional(parseString),
})

Annotate explicitly:

ts
type User = {
  id: number
  name?: string
}

const parseUser = object<User>({
  id: parseNumber,
  name: optional(parseString),
})

Limitations

Optional unknown properties will be inferred as required. See Infer > limitations for in-depth information.


objectCompiled()

ts
function objectCompiled<T>(schema): Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>

Same as object, but performs just-in-time (JIT) compilation with the Function constructor, which greatly increases the execution speed of the validation. However, the JIT compilation is slow and gets executed at the time when the validation function is constructed. When invoking this function at the module level, it is recommended to wrap it in lazy to defer the JIT compilation to when the validation function is called for the first time. This function will be blocked in environments where the Function constructor is blocked; for example, when the Content-Security-Policy policy is set without the 'unsafe-eval' directive.

See

  • object for a non-compiled version of this function.
  • lazy for deferring the JIT compilation.
  • objectStrictCompiled for a strict version.
  • object for a non-just-in-time compiled version of this function.

Example

Defer the JIT compilation to when the validation function is called for the first time.

ts
const isUser = lazy(() => objectCompiled({
 id: isNumber,
 name: isString,
})

Type Parameters

Type Parameter
T extends Record<string, unknown>

Parameters

ParameterTypeDescription
schema{ [K in string | number | symbol]-?: Object extends Pick<T, K> ? OptionalParser<T[K]> : Parser<T[K]> }maps keys to validation functions.

Returns

Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>


objectStrict()

ts
function objectStrict<T>(schema): Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>

Like object, but fails when the input data object has undeclared properties. Although object removes undeclared properties from the result, there are scenarios where you want to reject the input if it has extra properties.

See

object for a non-strict version.

Example

When designing APIs, you want to reject calls to the API that includes undeclared properties, as this will allow you to add new properties in the future without breaking changes.

For example, consider a REST API endpoint PUT /user/:id, which is validating the body with the non-strict object parser:

ts
const handlePutUser = (body: unknown) => {
 const parseBody = object({
   id: parseNumber,
   name: parseString,
 })
}

A client decides to call it with an extra property email:

ts
fetch('/user/1', {
 method: 'PUT',
 body: JSON.stringify({
   id: 123,
   name: 'Alice',
   email: null
}),

Since handlePutUser does not reject the API call, the client's success will succeed.

Now, the backend is updated to include the email property:

ts
const handlePutUser = (body: unknown) => {
 const parseBody = object({
   id: parseNumber,
   name: parseString,
   email: optional(parseString),
 })
}

That is, email is optional, but not nullable. If the client now sends the same request, it will suddenly fail.

To avoid such breaking change, use objectStrict:

ts
const handlePutUser = (body: unknown) => {
 const parseBody = objectStrict({
   id: parseNumber,
   name: parseString,
 })
}

Type Parameters

Type Parameter
T extends Record<string, unknown>

Parameters

ParameterTypeDescription
schema{ [K in string | number | symbol]-?: Object extends Pick<T, K> ? OptionalParser<T[K]> : Parser<T[K]> }

Returns

Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>


objectStrictCompiled()

ts
function objectStrictCompiled<T>(schema): Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>

Like objectCompiled, but fails when the input data object has undeclared properties in the same manner as objectStrict.

See

Type Parameters

Type Parameter
T extends Record<string, unknown>

Parameters

ParameterTypeDescription
schema{ [K in string | number | symbol]-?: Object extends Pick<T, K> ? OptionalParser<T[K]> : Parser<T[K]> }

Returns

Parser<OptionalKeys<T> extends undefined ? T : WithOptionalFields<T>>