suretype
suretype copied to clipboard
bug: defaults are not working correctly
The defaults
option is not working correctly.
In the following example, I have two approaches, both of which are faulty.
should fill in defaults with require
In this case, I am expecting the default to be set to 0, and then mark it as required, thereby eliminating the undefined
from the resulting inferred type. Without the require
at the end, num
will have number | undefined
type.
should fill in defaults without require
Here's an example without require at the end. When doing the addition in the last step, a TypeScript error is produced, because the type is number | undefined
:
Object is possibly 'undefined'. ts(2532)
import { compile, v } from 'suretype'
describe('suretype', () => {
it('should fill in defaults with require', () => {
expect.assertions(1)
const schema = v.object({
num: v.number().default(0).required(),
})
const validator = compile(schema, { ensure: true })
const result = validator({})
expect(result.num).toStrictEqual(0)
})
it('should fill in defaults without require', () => {
expect.assertions(1)
const schema = v.object({
num: v.number().default(0),
})
const validator = compile(schema, { ensure: true })
const result = validator({})
expect(result.num + 1).toStrictEqual(1)
})
})
FAIL test/valid.test.ts
suretype
✕ should fill in defaults with require (39 ms)
✕ should fill in defaults without require (7 ms)
● suretype › should fill in defaults with require
Validation failed
11 | const validator = compile(schema, { ensure: true })
12 |
> 13 | const result = validator({})
| ^
14 |
15 | expect(result.num).toStrictEqual(0)
16 | })
at validate (node_modules/suretype/dist/json-schema.js:45:19)
at Object.<anonymous> (test/valid.test.ts:13:20)
● suretype › should fill in defaults with require
expect.assertions(1)
Expected one assertion to be called but received zero assertion calls.
3 | describe('suretype', () => {
4 | it('should fill in defaults with require', () => {
> 5 | expect.assertions(1)
| ^
6 |
7 | const schema = v.object({
8 | num: v.number().default(0).required(),
at Object.<anonymous> (test/valid.test.ts:5:12)
● suretype › should fill in defaults without require
expect(received).toStrictEqual(expected) // deep equality
Expected: 1
Received: NaN
27 | const result = validator({})
28 |
> 29 | expect(result.num + 1).toStrictEqual(1)
| ^
30 | })
31 | })
32 |
at Object.<anonymous> (test/valid.test.ts:29:28)
Just realized this can be fixed with the following:
const validator = compile(schema, { ensure: true, ajvOptions: { useDefaults: true } })
But IMO, there is still a partial issue here.
I would expect the following:
v.number().default(0)
To result a type of number, rather than
number | undefined`.
Sorry for the late response, the partial issue is still there, and will be fixed by inverting the required/optional feature in the next major version of SureType.
useDefaults
will become default in v4 too, so you won't need to set that manually.