[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) › lazy

```ts
function lazy<Target>(
  getType: Thunk<ValidateLazyTarget<Target>>,
): LazyType<
  Target["Input"],
  Target["Output"],
  TypeFromError<Target>,
  InferErrors<RootType<Target>>,
  InferErrors<Target>,
  CanonicalInputOf<Target>,
  IdentityEncodingOf<Target>
>;
```

Defined in: [packages/common/src/Type.ts:12876](https://github.com/evoluhq/evolu/blob/f0109fb501a593010e858e39248dde1200eeb2d7/packages/common/src/Type.ts#L12876)

Creates a lazy [Type](https://evolu.dev/docs/api-reference/common/Type/interfaces/Type) for recursive definitions.

The definition is evaluated on first use and then cached, allowing recursive
data such as trees and mutually recursive models.

A recursive declaration refers to its own variable while that variable is
being initialized, so TypeScript cannot infer it reliably. Getter-based
inference tricks are brittle once optional properties, unions, or mutually
recursive definitions are involved. Declare recursive data interfaces and
structured error types explicitly for stable inference and clearer compiler
errors.

The definition must return one concrete non-Lazy Type. Use [union](https://evolu.dev/docs/api-reference/common/Type/functions/union) for
alternatives. Every recursive Lazy reference must be nested behind an
[object](https://evolu.dev/docs/api-reference/common/Type/functions/object), [array](https://evolu.dev/docs/api-reference/common/Type/functions/array), [tuple](https://evolu.dev/docs/api-reference/common/Type/functions/tuple), [record](https://evolu.dev/docs/api-reference/common/Type/functions/record), [set](https://evolu.dev/docs/api-reference/common/Type/functions/set), or
[map](https://evolu.dev/docs/api-reference/common/Type/functions/map) structural boundary. Union does not guard recursion because it
passes the same value to every member. Lazy defers schema construction; it
does not make cyclic runtime object graphs or arbitrarily deep values
stack-safe.

### Example

```ts
import {
  assertOk,
  assertType,
  String,
  array,
  lazy,
  object,
  type ArrayError,
  type LazyType,
  type ObjectError,
  type TypeOfError,
} from "@evolu/common";

interface Tree {
  readonly value: string;
  readonly children: ReadonlyArray<Tree>;
}

interface TreeError extends ObjectError<{
  readonly value: TypeOfError<"String">;
  readonly children: ArrayError<TreeError>;
}> {}

const Tree: LazyType<Tree, Tree, never, TreeError, TreeError> = lazy(() =>
  object({ value: String, children: array(Tree) }),
);

const result = Tree.fromUnknown({
  value: "root",
  children: [{ value: "leaf", children: [] }],
});

assertOk(result, {
  value: "root",
  children: [{ value: "leaf", children: [] }],
});
assertType<Tree, typeof result.value>();
```