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

## Call Signature

```ts
function withDefault<T, Value>(
  property: OptionalProperty<T> & {
    type: ValidateDefaultType<T, true>;
  },
  value: Value,
): WithDefaultProperty<T, Value, "replace">;
```

Defined in: [packages/common/src/Type.ts:12005](https://github.com/evoluhq/evolu/blob/dd96d79f1dbe9a49fa12ce8e0aa7d3d0177795ca/packages/common/src/Type.ts#L12005)

Supplies a decoded default for absence accepted by another [Type](https://evolu.dev/docs/api-reference/common/Type/interfaces/Type).

You might not need this: use `??` where a value is consumed if the default
does not need to become part of the decoded data. By default, replacement
loses the distinction between absence and an explicitly supplied value. Set
`strategy: "preserve"` to retain it.

Defaults apply after decoding, to `null` and `undefined` accepted by the
wrapped Type, and to missing properties when wrapping [optional](https://evolu.dev/docs/api-reference/common/Type/functions/optional). Types
whose Output excludes both `null` and `undefined` require `optional`;
otherwise there is no accepted absence to default. Invalid supplied values
still fail. An optional property does not accept an explicit `undefined`
unless its Type does. The default must be an Output of the wrapped Type; it
is checked when constructing the declaration. It may itself be `null` or
`undefined` when the wrapped Output accepts that value.

Omitting `strategy` returns the effective value and encodes it as supplied
data. `strategy: "preserve"` returns [Defaulted](https://evolu.dev/docs/api-reference/common/Type/type-aliases/Defaulted) and restores absence
when encoding. A supplied value equal to the default still has `defaultUsed:
false`. Preserved defaults must equal the configured value: [Data](https://evolu.dev/docs/api-reference/common/Type/variables/Data)
values use structural equality, and other values use reference identity.
Every decoded absence reuses the configured default by reference; defaults
are not cloned. Treat default values as immutable, like other Type
declarations.

Pass the default value as the second argument. Add `{ strategy: "preserve" }`
as the third argument to retain supplied-input evidence. Explicit `strategy:
"replace"` is not accepted.

### Example

```ts
import {
  assertEqual,
  assertErr,
  assertOk,
  Boolean,
  nullOr,
  object,
  optional,
  withDefault,
} from "@evolu/common";

const Settings = object({
  enabled: withDefault(optional(Boolean), true, {
    strategy: "preserve",
  }),
});

const missing = Settings.fromUnknown({});
assertOk(missing, {
  enabled: { value: true, defaultUsed: true, original: "missing" },
});
assertEqual(Settings.to(missing.value), {});

assertOk(Settings.fromUnknown({ enabled: true }), {
  enabled: { value: true, defaultUsed: false },
});
assertErr(Settings.fromUnknown({ enabled: undefined }));

const Enabled = withDefault(nullOr(Boolean), true);

assertOk(Enabled.fromUnknown(null), true);
assertEqual(Enabled.to(true), true);
```

## Call Signature

```ts
function withDefault<T, Value>(
  property: OptionalProperty<T> & {
    type: ValidateDefaultType<T, true>;
  },
  value: Value,
  options: {
    strategy: "preserve";
  },
): WithDefaultProperty<T, Value, "preserve">;
```

Defined in: [packages/common/src/Type.ts:12014](https://github.com/evoluhq/evolu/blob/dd96d79f1dbe9a49fa12ce8e0aa7d3d0177795ca/packages/common/src/Type.ts#L12014)

Supplies a decoded default for absence accepted by another [Type](https://evolu.dev/docs/api-reference/common/Type/interfaces/Type).

You might not need this: use `??` where a value is consumed if the default
does not need to become part of the decoded data. By default, replacement
loses the distinction between absence and an explicitly supplied value. Set
`strategy: "preserve"` to retain it.

Defaults apply after decoding, to `null` and `undefined` accepted by the
wrapped Type, and to missing properties when wrapping [optional](https://evolu.dev/docs/api-reference/common/Type/functions/optional). Types
whose Output excludes both `null` and `undefined` require `optional`;
otherwise there is no accepted absence to default. Invalid supplied values
still fail. An optional property does not accept an explicit `undefined`
unless its Type does. The default must be an Output of the wrapped Type; it
is checked when constructing the declaration. It may itself be `null` or
`undefined` when the wrapped Output accepts that value.

Omitting `strategy` returns the effective value and encodes it as supplied
data. `strategy: "preserve"` returns [Defaulted](https://evolu.dev/docs/api-reference/common/Type/type-aliases/Defaulted) and restores absence
when encoding. A supplied value equal to the default still has `defaultUsed:
false`. Preserved defaults must equal the configured value: [Data](https://evolu.dev/docs/api-reference/common/Type/variables/Data)
values use structural equality, and other values use reference identity.
Every decoded absence reuses the configured default by reference; defaults
are not cloned. Treat default values as immutable, like other Type
declarations.

Pass the default value as the second argument. Add `{ strategy: "preserve" }`
as the third argument to retain supplied-input evidence. Explicit `strategy:
"replace"` is not accepted.

### Example

```ts
import {
  assertEqual,
  assertErr,
  assertOk,
  Boolean,
  nullOr,
  object,
  optional,
  withDefault,
} from "@evolu/common";

const Settings = object({
  enabled: withDefault(optional(Boolean), true, {
    strategy: "preserve",
  }),
});

const missing = Settings.fromUnknown({});
assertOk(missing, {
  enabled: { value: true, defaultUsed: true, original: "missing" },
});
assertEqual(Settings.to(missing.value), {});

assertOk(Settings.fromUnknown({ enabled: true }), {
  enabled: { value: true, defaultUsed: false },
});
assertErr(Settings.fromUnknown({ enabled: undefined }));

const Enabled = withDefault(nullOr(Boolean), true);

assertOk(Enabled.fromUnknown(null), true);
assertEqual(Enabled.to(true), true);
```

## Call Signature

```ts
function withDefault<T, Value>(
  type: T &
    ValidateOptionalPropertyType<T> &
    [
      "WithDefault" extends InferErrors<T>["type"]
        ? "⛔ Type error: Error type must not duplicate an error inherited from the parent Type."
        : never,
    ] extends [never]
    ? unknown
    : "WithDefault" extends InferErrors<T>["type"]
      ? "⛔ Type error: Error type must not duplicate an error inherited from the parent Type."
      : never & [DefaultOriginal<T>] extends [never]
        ? "⛔ Type error: withDefault requires an optional property or a Type whose Output includes null or undefined."
        : unknown,
  value: Value,
): WithDefaultType<T, Value, "replace">;
```

Defined in: [packages/common/src/Type.ts:12024](https://github.com/evoluhq/evolu/blob/dd96d79f1dbe9a49fa12ce8e0aa7d3d0177795ca/packages/common/src/Type.ts#L12024)

Supplies a decoded default for absence accepted by another [Type](https://evolu.dev/docs/api-reference/common/Type/interfaces/Type).

You might not need this: use `??` where a value is consumed if the default
does not need to become part of the decoded data. By default, replacement
loses the distinction between absence and an explicitly supplied value. Set
`strategy: "preserve"` to retain it.

Defaults apply after decoding, to `null` and `undefined` accepted by the
wrapped Type, and to missing properties when wrapping [optional](https://evolu.dev/docs/api-reference/common/Type/functions/optional). Types
whose Output excludes both `null` and `undefined` require `optional`;
otherwise there is no accepted absence to default. Invalid supplied values
still fail. An optional property does not accept an explicit `undefined`
unless its Type does. The default must be an Output of the wrapped Type; it
is checked when constructing the declaration. It may itself be `null` or
`undefined` when the wrapped Output accepts that value.

Omitting `strategy` returns the effective value and encodes it as supplied
data. `strategy: "preserve"` returns [Defaulted](https://evolu.dev/docs/api-reference/common/Type/type-aliases/Defaulted) and restores absence
when encoding. A supplied value equal to the default still has `defaultUsed:
false`. Preserved defaults must equal the configured value: [Data](https://evolu.dev/docs/api-reference/common/Type/variables/Data)
values use structural equality, and other values use reference identity.
Every decoded absence reuses the configured default by reference; defaults
are not cloned. Treat default values as immutable, like other Type
declarations.

Pass the default value as the second argument. Add `{ strategy: "preserve" }`
as the third argument to retain supplied-input evidence. Explicit `strategy:
"replace"` is not accepted.

### Example

```ts
import {
  assertEqual,
  assertErr,
  assertOk,
  Boolean,
  nullOr,
  object,
  optional,
  withDefault,
} from "@evolu/common";

const Settings = object({
  enabled: withDefault(optional(Boolean), true, {
    strategy: "preserve",
  }),
});

const missing = Settings.fromUnknown({});
assertOk(missing, {
  enabled: { value: true, defaultUsed: true, original: "missing" },
});
assertEqual(Settings.to(missing.value), {});

assertOk(Settings.fromUnknown({ enabled: true }), {
  enabled: { value: true, defaultUsed: false },
});
assertErr(Settings.fromUnknown({ enabled: undefined }));

const Enabled = withDefault(nullOr(Boolean), true);

assertOk(Enabled.fromUnknown(null), true);
assertEqual(Enabled.to(true), true);
```

## Call Signature

```ts
function withDefault<T, Value>(
  type: T &
    ValidateOptionalPropertyType<T> &
    [
      "WithDefault" extends InferErrors<T>["type"]
        ? "⛔ Type error: Error type must not duplicate an error inherited from the parent Type."
        : never,
    ] extends [never]
    ? unknown
    : "WithDefault" extends InferErrors<T>["type"]
      ? "⛔ Type error: Error type must not duplicate an error inherited from the parent Type."
      : never & [DefaultOriginal<T>] extends [never]
        ? "⛔ Type error: withDefault requires an optional property or a Type whose Output includes null or undefined."
        : unknown,
  value: Value,
  options: {
    strategy: "preserve";
  },
): WithDefaultType<T, Value, "preserve">;
```

Defined in: [packages/common/src/Type.ts:12031](https://github.com/evoluhq/evolu/blob/dd96d79f1dbe9a49fa12ce8e0aa7d3d0177795ca/packages/common/src/Type.ts#L12031)

Supplies a decoded default for absence accepted by another [Type](https://evolu.dev/docs/api-reference/common/Type/interfaces/Type).

You might not need this: use `??` where a value is consumed if the default
does not need to become part of the decoded data. By default, replacement
loses the distinction between absence and an explicitly supplied value. Set
`strategy: "preserve"` to retain it.

Defaults apply after decoding, to `null` and `undefined` accepted by the
wrapped Type, and to missing properties when wrapping [optional](https://evolu.dev/docs/api-reference/common/Type/functions/optional). Types
whose Output excludes both `null` and `undefined` require `optional`;
otherwise there is no accepted absence to default. Invalid supplied values
still fail. An optional property does not accept an explicit `undefined`
unless its Type does. The default must be an Output of the wrapped Type; it
is checked when constructing the declaration. It may itself be `null` or
`undefined` when the wrapped Output accepts that value.

Omitting `strategy` returns the effective value and encodes it as supplied
data. `strategy: "preserve"` returns [Defaulted](https://evolu.dev/docs/api-reference/common/Type/type-aliases/Defaulted) and restores absence
when encoding. A supplied value equal to the default still has `defaultUsed:
false`. Preserved defaults must equal the configured value: [Data](https://evolu.dev/docs/api-reference/common/Type/variables/Data)
values use structural equality, and other values use reference identity.
Every decoded absence reuses the configured default by reference; defaults
are not cloned. Treat default values as immutable, like other Type
declarations.

Pass the default value as the second argument. Add `{ strategy: "preserve" }`
as the third argument to retain supplied-input evidence. Explicit `strategy:
"replace"` is not accepted.

### Example

```ts
import {
  assertEqual,
  assertErr,
  assertOk,
  Boolean,
  nullOr,
  object,
  optional,
  withDefault,
} from "@evolu/common";

const Settings = object({
  enabled: withDefault(optional(Boolean), true, {
    strategy: "preserve",
  }),
});

const missing = Settings.fromUnknown({});
assertOk(missing, {
  enabled: { value: true, defaultUsed: true, original: "missing" },
});
assertEqual(Settings.to(missing.value), {});

assertOk(Settings.fromUnknown({ enabled: true }), {
  enabled: { value: true, defaultUsed: false },
});
assertErr(Settings.fromUnknown({ enabled: undefined }));

const Enabled = withDefault(nullOr(Boolean), true);

assertOk(Enabled.fromUnknown(null), true);
assertEqual(Enabled.to(true), true);
```