question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

defined() allows null to validate

See original GitHub issue

Describe the bug

Calling defined on any schema will allow null to pass validation, unless required is also included or nullable(false) is called after calling defined.

Discovered while discussing in https://github.com/DefinitelyTyped/DefinitelyTyped/pull/45244.

number().isValidSync(null); // false
number().defined().isValidSync(null); // true (!!)
number().nullable(false).defined().isValidSync(null); // true (!!)
number().required().defined().isValidSync(null); // false

To Reproduce

https://codesandbox.io/s/hopeful-diffie-tp9l7

Expected behavior

defined should only disallow undefined – it should never affect the allowance or disallowance of null.

Platform (please complete the following information):

  • Browser: Edge
  • Version: 83

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:13 (9 by maintainers)

github_iconTop GitHub Comments

2reactions
danieldiekmeiercommented, Aug 21, 2020

I also just stumbled over this. In TypeScript, the types don’t match the actual allowed values after validation.

Correct:

const schema = yup.string()
// Inferred type: 
const schema: yup.StringSchema<string | undefined>

Also correct:

const schema = yup.string().required()
// Inferred type: 
const schema: yup.StringSchema<string>

This is the problem case:

const schema = yup.string().defined()
// Inferred type: 
const schema: yup.StringSchema<string>

// The inferred type should be yup.StringSchema<string | null>, because this works:
const x = schema.validateSync(null)
// x now has the inferred type `string`, even though its value is `null`

To make sure the inferred types are correct, you have to call nullable anyway:

const schema = yup.string().defined().nullable(false)
// Inferred type: 
const schema: yup.StringSchema<string>

The documentation for this is correct, but the types are incorrect and led me to a lot of head scratching.

1reaction
jquensecommented, Jun 3, 2020

.defined().nullable(false) and .nullable().present() (or notNullOrUndefined) wouldn’t be equivalent and solve slightly different use cases. The former strictly bans null, whereas the latter allows it as a value but fails validation.

e.g.

string().defined().cast(null) // throws TypeError
string().validate(null) // throws ValidationError

but

// validates against undefined and null
string().nullable().present().cast(null) // -> null
string().nullable().present().validate(null) // throws ValidationError

The reason you might want the second but not the first is when parsing server responses, e.g. you fetch from an API, then cast the JSON, manipulate it and then validate after, at which point you want required values to be filled and throw if they aren’t. Mentioning this mostly to clarify my own thinking for when invariably read this months from now contemplating changing something again 😛

Read more comments on GitHub >

github_iconTop Results From Across the Web

class validator - How to allow null, but forbid undefined?
It turns out that this is possible by using conditional validation ValidateIf : class DbRow { @IsNumber() id!: number; @IsNumber() ...
Read more >
What does it mean to do a "null check" in C or C++?
That means returning a (pointer - or even better, reference to an) empty array or list instead of null, or returning an empty...
Read more >
Null safety | Kotlin Documentation
To allow nulls, you can declare a variable as a nullable string ... For example, the toString() function is defined on a nullable...
Read more >
Validations & Constraints - Sequelize
The allowNull check is the only check in Sequelize that is a mix of a validation and a constraint in the senses described...
Read more >
21.2 Validating Null and Empty Strings
Suppose, on the other hand, that you have a @NotNull constraint on an element, meaning that input is required. In this case, an...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found