Skip to content

Commit 8aaad50

Browse files
committed
Mark .optional(() => ...) as non-experimental
1 parent 026567f commit 8aaad50

3 files changed

Lines changed: 23 additions & 9 deletions

File tree

.changeset/calm-bugs-fail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@badrap/valita": patch
3+
---
4+
5+
Mark `.optional(() => ...)` as non-experimental and recommend it over the now-deprecated `.default(x)`

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,13 +299,13 @@ const t = v.string().optional();
299299
t.parse("Hello, World!");
300300
```
301301

302-
The `.default(...)` method can be used to set a default value for a missing or undefined value.
302+
An optional function can be used to replace a missing or undefined values with some other default value:
303303

304304
```ts
305305
const person = v.object({
306306
name: v.string(),
307307
// Set a sensible default for those unwilling to fill in their theme song
308-
themeSong: v.string().default("Tribute"),
308+
themeSong: v.string().optional(() => "Tribute"),
309309
});
310310

311311
person.parse({ name: "Jane Doe", themeSong: "Never gonna give you up" });
@@ -316,6 +316,8 @@ person.parse({ name: "Jane Doe", themeSong: undefined });
316316
// { name: "Jane Doe", themeSong: "Tribute" }
317317
```
318318

319+
The default function is re-evaluated every for every missing or undefined value to avoid accidentally sharing mutable default values like objects or arrays between different parsed values.
320+
319321
### Array Types
320322

321323
The `v.array(...)` combinator can be used to check that the value is an array, and that its items have a specific type. The validated arrays may be of arbitrary length, including empty arrays.

src/index.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,17 @@ abstract class AbstractType<Output = unknown> {
437437
abstract toTerminals(func: (t: TerminalType) => void): void;
438438
abstract func(v: unknown, flags: number): RawResult<Output>;
439439

440-
/** @experimental */
440+
/**
441+
* Return new optional type that can not be used as a standalone
442+
* validator. Rather, it's meant to be used as a with object validators,
443+
* to mark one of the object's properties as _optional_. Optional property
444+
* types accept both the original type, `undefined` and missing properties.
445+
*
446+
* The optional `defaultFn` function, if provided, will be called each
447+
* time a value that is missing or `undefined` is parsed.
448+
*
449+
* @param [defaultFn] - An optional function returning the default value.
450+
*/
441451
// Use `<X extends T>() => X` instead of `() => T` to make literal
442452
// inference work when an optionals with defaultFn is used as a
443453
// ObjectType property.
@@ -455,12 +465,6 @@ abstract class AbstractType<Output = unknown> {
455465
defaultFn: () => Exclude<Output, undefined>,
456466
): Type<Exclude<Output, undefined>>;
457467
optional<T>(defaultFn: () => T): Type<Exclude<Output, undefined> | T>;
458-
/**
459-
* Return new optional type that can not be used as a standalone
460-
* validator. Rather, it's meant to be used as a with object validators,
461-
* to mark one of the object's properties as _optional_. Optional property
462-
* types accept both the original type, `undefined` and missing properties.
463-
*/
464468
optional(): Optional<Output>;
465469
optional<T>(
466470
defaultFn?: () => T,
@@ -474,6 +478,9 @@ abstract class AbstractType<Output = unknown> {
474478
});
475479
}
476480

481+
/**
482+
* @deprecated Instead of `.default(x)` use `.optional(() => x)`.
483+
*/
477484
default<T extends Literal>(
478485
defaultValue: T,
479486
): Type<Exclude<Output, undefined> | T>;

0 commit comments

Comments
 (0)