Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update readme to account for changes in types and add additional example #891

Merged
merged 5 commits into from
May 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
## [0.29.0](https://github.com/jquense/yup/compare/v0.28.5...v0.29.0) (2020-05-15)


### BREAKING CHANGES

* the types ([@types/yup](https://www.npmjs.com/package/@types/yup)) have been updated to include `undefined` by default. TypeScript users can add `.defined()` to their schemas to account for this.


## [0.28.5](https://github.com/jquense/yup/compare/v0.28.4...v0.28.5) (2020-04-30)


Expand Down
43 changes: 31 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ Yup's API is heavily inspired by [Joi](https://github.com/hapijs/joi), but leane
- [Extending Schema Types](#extending-schema-types)
- [TypeScript Support](#typescript-support)
- [TypeScript setting](#typescript-setting)
- [Why does InferType not default to nonRequired()?](#why-does-infertype-not-default-to-nonrequired)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand Down Expand Up @@ -1280,7 +1279,7 @@ schema.format('YYYY-MM-DD').cast('It is 2012-05-25'); // => Fri May 25 2012 00:0

## TypeScript Support

If you are using TypeScript installing the Yup typings is recommended
If you are using TypeScript installing the Yup typings is recommended:

```sh
npm install -D @types/yup
Expand All @@ -1293,13 +1292,22 @@ import * as yup from 'yup';

const personSchema = yup.object({
firstName: yup
.string(),
.string()
// Here we use `defined` instead of `required` to more closely align with
// TypeScript. Both will have the same effect on the resulting type by
// excluding `undefined`, but `required` will also disallow other values
// such as empty strings.
.defined(),
iansan5653 marked this conversation as resolved.
Show resolved Hide resolved
nickName: yup
.string()
.defined()
.nullable(),
gender: yup
.mixed<'male' | 'female' | 'other'>()
.oneOf(['male', 'female', 'other']),
.mixed()
// Note `as const`: this types the array as `["male", "female", "other"]`
// instead of `string[]`.
.oneOf(['male', 'female', 'other'] as const)
.defined(),
email: yup
.string()
.nullable()
Expand All @@ -1310,7 +1318,7 @@ const personSchema = yup.object({
.nullable()
.notRequired()
.min(new Date(1900, 0, 1)),
});
}).defined();
```

You can derive the TypeScript type as follows:
Expand Down Expand Up @@ -1349,14 +1357,25 @@ const fullPerson: Person = {
};
```

### TypeScript setting
You can also go the other direction, specifying an interface and ensuring that a schema matches it:

For `yup.InferType<T>` to work correctly with required and nullable types you have to set `strict: true` or `strictNullChecks: true` in your tsconfig.json.
```TypeScript
type Person = {
firstName: string;
}

### Why does InferType not default to nonRequired()?
// ✔️ compiles
const goodPersonSchema: yup.ObjectSchema<Person> = yup.object({
firstName: yup.string().defined()
}).defined();

This was considered when implementing `InferType<T>` but was decided against.
// ❌ errors:
// "Type 'number | undefined' is not assignable to type 'string'."
const badPersonSchema: yup.ObjectSchema<Person> = yup.object({
firstName: yup.number()
});
```

The semantics of a required property in Yup is not the same as in TypeScript. For example a `Yup.array().of(Yup.string()).required()` will fail validation if you pass in an empty array. A required array should not be empty: [empty arrays are also considered 'missing' values](#arrayrequiredmessage-string--function-schema). The same is true for a `Yup.string().required()` where passing in an empty string `""` is considered invalid while the non-empty string: `"hello"` is considered valid. With TypeScript both would satisfy required. Another example of that is a `Yup.date()` that will pass validation if you use the string `"2020-02-14T07:52:25.495Z"` if you don't call `.strict()`.
### TypeScript setting

In general there isn't a one to one match between Yup and TypeScript concepts so this is never going to be perfect.
For `yup.InferType<T>` to work correctly with required and nullable types you have to set `strict: true` or `strictNullChecks: true` in your tsconfig.json.