Skip to content

Commit

Permalink
Update objects guide on website
Browse files Browse the repository at this point in the history
  • Loading branch information
fabian-hiller committed May 21, 2024
1 parent 64c7cba commit aeab1ef
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 87 deletions.
18 changes: 8 additions & 10 deletions library/src/schemas/object/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ export interface ObjectSchema<
/**
* Creates an object schema.
*
* Hint: This schema ignores and excludes unknown entries. The output will
* include only the entries you specify. To include unknown entries, use the
* `looseObject` schema. To return an issue for unknown entries, use the
* `strictObject` schema. To include and validate unknown entries, use the
* `objectWithRest` schema.
* Hint: This schema removes unknown entries. The output will only include the
* entries you specify. To include unknown entries, use `looseObject`. To
* return an issue for unknown entries, use `strictObject`. To include and
* validate unknown entries, use `objectWithRest`.
*
* @param entries The entries schema.
*
Expand All @@ -64,11 +63,10 @@ export function object<const TEntries extends ObjectEntries>(
/**
* Creates an object schema.
*
* Hint: This schema ignores and excludes unknown entries. The output will
* include only the entries you specify. To include unknown entries, use the
* `looseObject` schema. To return an issue for unknown entries, use the
* `strictObject` schema. To include and validate unknown entries, use the
* `objectWithRest` schema.
* Hint: This schema removes unknown entries. The output will only include the
* entries you specify. To include unknown entries, use `looseObject`. To
* return an issue for unknown entries, use `strictObject`. To include and
* validate unknown entries, use `objectWithRest`.
*
* @param entries The entries schema.
* @param message The error message.
Expand Down
18 changes: 8 additions & 10 deletions library/src/schemas/object/objectAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,10 @@ export interface ObjectSchemaAsync<
/**
* Creates an object schema.
*
* Hint: This schema ignores and excludes unknown entries. The output will
* include only the entries you specify. To include unknown entries, use the
* `looseObjectAsync` schema. To return an issue for unknown entries, use the
* `strictObjectAsync` schema. To include and validate unknown entries, use the
* `objectWithRestAsync` schema.
* Hint: This schema removes unknown entries. The output will only include the
* entries you specify. To include unknown entries, use `looseObjectAsync`. To
* return an issue for unknown entries, use `strictObjectAsync`. To include and
* validate unknown entries, use `objectWithRestAsync`.
*
* @param entries The entries schema.
*
Expand All @@ -64,11 +63,10 @@ export function objectAsync<const TEntries extends ObjectEntriesAsync>(
/**
* Creates an object schema.
*
* Hint: This schema ignores and excludes unknown entries. The output will
* include only the entries you specify. To include unknown entries, use the
* `looseObjectAsync` schema. To return an issue for unknown entries, use the
* `strictObjectAsync` schema. To include and validate unknown entries, use the
* `objectWithRestAsync` schema.
* Hint: This schema removes unknown entries. The output will only include the
* entries you specify. To include unknown entries, use `looseObjectAsync`. To
* return an issue for unknown entries, use `strictObjectAsync`. To include and
* validate unknown entries, use `objectWithRestAsync`.
*
* @param entries The entries schema.
* @param message The error message.
Expand Down
18 changes: 8 additions & 10 deletions library/src/schemas/tuple/tuple.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ export interface TupleSchema<
/**
* Creates a tuple schema.
*
* Hint: This schema ignores and excludes unknown items. The output will
* include only the items you specify. To include unknown items, use the
* `looseTuple` schema. To return an issue for unknown items, use the
* `strictTuple` schema. To include and validate unknown items, use the
* `tupleWithRest` schema.
* Hint: This schema removes unknown items. The output will only include the
* items you specify. To include unknown items, use `looseTuple`. To
* return an issue for unknown items, use `strictTuple`. To include and
* validate unknown items, use `tupleWithRest`.
*
* @param items The items schema.
*
Expand All @@ -65,11 +64,10 @@ export function tuple<const TItems extends TupleItems>(
/**
* Creates a tuple schema.
*
* Hint: This schema ignores and excludes unknown items. The output will
* include only the items you specify. To include unknown items, use the
* `looseTuple` schema. To return an issue for unknown items, use the
* `strictTuple` schema. To include and validate unknown items, use the
* `tupleWithRest` schema.
* Hint: This schema removes unknown items. The output will only include the
* items you specify. To include unknown items, use `looseTuple`. To
* return an issue for unknown items, use `strictTuple`. To include and
* validate unknown items, use `tupleWithRest`.
*
* @param items The items schema.
* @param message The error message.
Expand Down
18 changes: 8 additions & 10 deletions library/src/schemas/tuple/tupleAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,10 @@ export interface TupleSchemaAsync<
/**
* Creates a tuple schema.
*
* Hint: This schema ignores and excludes unknown items. The output will
* include only the items you specify. To include unknown items, use the
* `looseTupleAsync` schema. To return an issue for unknown items, use the
* `strictTupleAsync` schema. To include and validate unknown items, use the
* `tupleWithRestAsync` schema.
* Hint: This schema removes unknown items. The output will only include the
* items you specify. To include unknown items, use `looseTupleAsync`. To
* return an issue for unknown items, use `strictTupleAsync`. To include and
* validate unknown items, use `tupleWithRestAsync`.
*
* @param items The items schema.
*
Expand All @@ -65,11 +64,10 @@ export function tupleAsync<const TItems extends TupleItemsAsync>(
/**
* Creates a tuple schema.
*
* Hint: This schema ignores and excludes unknown items. The output will
* include only the items you specify. To include unknown items, use the
* `looseTupleAsync` schema. To return an issue for unknown items, use the
* `strictTupleAsync` schema. To include and validate unknown items, use the
* `tupleWithRestAsync` schema.
* Hint: This schema removes unknown items. The output will only include the
* items you specify. To include unknown items, use `looseTupleAsync`. To
* return an issue for unknown items, use `strictTupleAsync`. To include and
* validate unknown items, use `tupleWithRestAsync`.
*
* @param items The items schema.
* @param message The error message.
Expand Down
80 changes: 33 additions & 47 deletions website/src/routes/guides/(schemas)/objects/index.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
title: Objects
description: >-
To validate objects with a schema, you can use object or record. You use
object for an object with a specific shape and record in the other case.
To validate objects with a schema, you can use `object` or `record`. You use
`object` for an object with a specific shape and `record` in the other case.
contributors:
- fabian-hiller
---
Expand All @@ -15,7 +15,7 @@ To validate objects with a schema, you can use <Link href="/api/object/">`object

## Object schema

The first argument is used to define the specific structure of the object. Each entry consists of a key and a schema as the value. The entries are then validated against the key and schema.
The first argument is used to define the specific structure of the object. Each entry consists of a key and a schema as the value. The entries of the input are then validated against these schemas.

```ts
import * as v from 'valibot';
Expand All @@ -26,105 +26,91 @@ const ObjectSchema = v.object({
});
```

### Rest argument
### Loose and strict objects

By default, <Link href="/api/object/">`object`</Link> ignores and removes unknown entries. This means that entries that you have not defined in the first argument will not be validated and will not be added to the output. You can control this behavior with the `rest` argument.
The <Link href="/api/object/">`object`</Link> schema removes unknown entries. This means that entries that you have not defined in the first argument are not validated and added to the output. You can change this behavior by using the <Link href="/api/looseObject/">`looseObject`</Link> or <Link href="/api/strictObject/">`strictObject`</Link> schema instead.

By using <Link href="/api/never/">`never`</Link> for the `rest` argument, you can make the validation strict and forbid unknown entries completely. If unknown entries are detected, an issue is returned for each entry.
The <Link href="/api/looseObject/">`looseObject`</Link> schema allows unknown entries and adds them to the output. The <Link href="/api/strictObject/">`strictObject`</Link> schema forbids unknown entries and returns an issue for the first unknown entry found.

```ts
import * as v from 'valibot';

const ObjectSchema = v.object(
{
key1: v.string(),
key2: v.number(),
},
v.never()
);
```
### Object with specific rest

Alternatively, you can also allow unknown entries with <Link href="/api/unknown/">`unknown`</Link> and add them to the output. Instead of <Link href="/api/unknown/">`unknown`</Link>, you can also use any other schema function, such as <Link href="/api/string/">`string`</Link>, for a typed output.
Alternatively, you can also use the <Link href="/api/objectWithRest/">`objectWithRest`</Link> schema to define a specific schema for unknown entries. Any entries not defined in the first argument are then validated against the schema in the second argument.

```ts
import * as v from 'valibot';

const ObjectSchema = v.object(
const ObjectSchema = v.objectWithRest(
{
key1: v.string(),
key2: v.number(),
},
v.unknown()
v.null_()
);
```

### Pipeline validation
### Complex object validation

To validate the value of an entry based on another entry, you can use <Link href="/api/custom/">`custom`</Link> in the object's pipeline. You can also use <Link href="/api/forward/">`forward`</Link> to assign the issue to a specific object key in the event of an error.
To validate the value of an entry based on another entry, you can wrap you schema with the <Link href="/api/check/">`check`</Link> validation action in a pipeline. You can also use <Link href="/api/forward/">`forward`</Link> to assign the issue to a specific object key in the event of an error.

```ts
import * as v from 'valibot';

const CalculationSchema = v.object(
{
const CalculationSchema = v.pipe(
v.object({
a: v.number(),
b: v.number(),
sum: v.number(),
},
[
v.forward(
v.custom(
({ a, b, sum }) => a + b === sum,
'The calculation is incorrect.'
),
['sum']
),
]
}),
v.forward(
v.check(({ a, b, sum }) => a + b === sum, 'The calculation is incorrect.'),
['sum']
)
);
```

## Record schema

For an object with any number of uniform entries, <Link href="/api/record/">`record`</Link> is the right choice. If you pass only one schema as an argument to the function, this will be used to validate the values of the record. In this case, the keys are automatically validated with <Link href="/api/string/">`string`</Link>.
For an object with any number of uniform entries, <Link href="/api/record/">`record`</Link> is the right choice. The schema passed as the first argument validates the keys of your record, and the schema passed as the second argument validates the values.

```ts
import * as v from 'valibot';

const RecordSchema = v.record(v.number()); // Record<string, number>
const RecordSchema = v.record(v.string(), v.number()); // Record<string, number>
```

### Key argument
### Specific record keys

To explicitly define the schema of the keys, you can pass two schemas to <Link href="/api/record/">`record`</Link>. The first schema will be used for the keys and the second schema for the values.
Instead of <Link href="/api/string/">`string`</Link>, you can also use <Link href="/api/custom/">`custom`</Link>, <Link href="/api/enum_/">`enum_`</Link>, <Link href="/api/literal/">`literal`</Link>, <Link href="/api/picklist/">`picklist`</Link> or <Link href="/api/union/">`union`</Link> to validate the keys.

```ts
import * as v from 'valibot';

const RecordSchema = v.record(v.string(), v.number()); // Record<string, number>
const RecordSchema = v.record(v.picklist(['key1', 'key2']), v.number()); // { key1?: number; key2?: number }
```

Instead of <Link href="/api/string/">`string`</Link>, you can also use <Link href="/api/enum_/">`enum_`</Link>, <Link href="/api/picklist/">`picklist`</Link>, <Link href="/api/special/">`special`</Link> or <Link href="/api/union/">`union`</Link> to validate the keys.
Note that <Link href="/api/record/">`record`</Link> marks all literal keys as optional in this case. If you want to make them required, you can use the <Link href="/api/object/">`object`</Link> schema with the `entriesFromList` util instead.

```ts
import * as v from 'valibot';

const RecordSchema = v.record(v.picklist(['key1', 'key2']), v.number()); // { key1?: number; key2?: number }
const RecordSchema = v.object(v.entriesFromList(['key1', 'key2'], v.number())); // { key1: number; key2: number }
```

### Pipeline validation
### Complex record validation

To validate the value of an entry based on another entry, you can use <Link href="/api/custom/">`custom`</Link> in the records's pipeline. You can also use <Link href="/api/forward/">`forward`</Link> to assign the issue to a specific record key in the event of an error.
To validate the value of an entry based on another entry, you can wrap you schema with the <Link href="/api/check/">`check`</Link> validation action in a pipeline. You can also use <Link href="/api/forward/">`forward`</Link> to assign the issue to a specific record key in the event of an error.

```ts
import * as v from 'valibot';

const CalculationSchema = v.record(v.picklist(['a', 'b', 'sum']), v.number(), [
const CalculationSchema = v.pipe(
v.record(v.picklist(['a', 'b', 'sum']), v.number()),
v.forward(
v.custom(
v.check(
({ a, b, sum }) => (a || 0) + (b || 0) === (sum || 0),
'The calculation is incorrect.'
),
['sum']
),
]);
)
);
```

0 comments on commit aeab1ef

Please sign in to comment.