If we want to validate an object with optional parameters for a spread:
type Hotdog = {
length: number;
topping: string;
}
function patchHotdog(hotdog: Hotdog, patchBody: unknown): Hotdog {
ow(
patchBody,
ow.object.exactShape({
length: ow.optional.number,
topping: ow.optional.string,
})
)
return {
...hotdog,
...patchBody
}
// ERROR:
//TS2322: Type '{ length: number | undefined; topping: string | undefined; }' is not assignable to type 'Hotdog'.
// Types of property 'length' are incompatible.
// Type 'number | undefined' is not assignable to type 'number'.
// Type 'undefined' is not assignable to type 'number'.
}
This doesn't work, as ow will assert patchBody
as
type ValidatedPatchBody = {
length: number | undefined;
topping: string | undefined;
}
when really we want
type ValidatedPatchBody = {
length?: number;
topping?: string;
}
Which makes a difference, as js treats undefined value and no key differently when spreading:
const obj1 = { bar: 'foo', ...{} } // => { bar: 'foo' }
const obj2 = { bar: 'foo', ...{ bar: undefined } } // => { bar: undefined }
Unless I'm missing something, it doesn't look like ow
provides a way to do this out of the box.
In the mean time, I've worked around this by passing in an explicit type argument:
function patchHotdog(hotdog: Hotdog, patchBody: unknown): Hotdog {
ow<{length?: number, topping?:string}>(
patchBody,
ow.object.exactShape({
length: ow.optional.number,
topping: ow.optional.string,
})
)
return {
...hotdog,
...patchBody
} // IT OKAY
}
Pay now to fund the work behind this issue.
Get updates on progress being made.
Maintainer is rewarded once the issue is completed.
You're funding impactful open source efforts
You want to contribute to this effort
You want to get funding like this too