Skip to content

Commit

Permalink
feat!: update docs to account for changes in types and add additional…
Browse files Browse the repository at this point in the history
… example (#891)

BREAKING CHANGE: For users of `@types/yup` only, no function changes but the type def change is large enough that it warranted a major bump here
  • Loading branch information
iansan5653 authored May 19, 2020
1 parent 08dad5f commit e105a71
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 12 deletions.
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(),
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.

0 comments on commit e105a71

Please sign in to comment.