From e105a716dbd89fef794d2f90bfdf657fb8b9428c Mon Sep 17 00:00:00 2001 From: Ian Sanders Date: Tue, 19 May 2020 13:59:46 -0400 Subject: [PATCH] feat!: update docs to account for changes in types and add additional 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 --- CHANGELOG.md | 8 ++++++++ README.md | 43 +++++++++++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3891ba255..e16966f8f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/README.md b/README.md index 962f1e6e3..de6978e80 100644 --- a/README.md +++ b/README.md @@ -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) @@ -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 @@ -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() @@ -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: @@ -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` 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 = yup.object({ + firstName: yup.string().defined() +}).defined(); -This was considered when implementing `InferType` but was decided against. +// ❌ errors: +// "Type 'number | undefined' is not assignable to type 'string'." +const badPersonSchema: yup.ObjectSchema = 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` to work correctly with required and nullable types you have to set `strict: true` or `strictNullChecks: true` in your tsconfig.json.