API reference › @evolu/common › Type › withDefault
Call Signature
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
Supplies a decoded default for absence accepted by another 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. 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 and restores absence
when encoding. A supplied value equal to the default still has defaultUsed: false. Preserved defaults must equal the configured value: 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
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
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
Supplies a decoded default for absence accepted by another 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. 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 and restores absence
when encoding. A supplied value equal to the default still has defaultUsed: false. Preserved defaults must equal the configured value: 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
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
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
Supplies a decoded default for absence accepted by another 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. 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 and restores absence
when encoding. A supplied value equal to the default still has defaultUsed: false. Preserved defaults must equal the configured value: 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
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
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
Supplies a decoded default for absence accepted by another 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. 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 and restores absence
when encoding. A supplied value equal to the default still has defaultUsed: false. Preserved defaults must equal the configured value: 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
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);