Closed efenderbosch closed 4 years ago
What Type
do you want to express? If you want something like Type<Option<NonEmptyString>, string | null>
you could do optionFromNullable(nonEmptyString)
.
I want to avoid form submission that ends up with JSON like:
{
"foo": "someValue",
"bar": ""
}
being sent to the server.
What should be sent instead is:
{
"foo": "someValue"
}
Server-side validation is enforcing an if-present-must-not-be-blank rule. However, simply tabbing through the input on the form and hitting submit is sending the empty string.
Right now I have a few custom "types", including:
export const nullAsUndefined = fromNullable(iots.undefined, undefined)
export const OptionalString = iots.union([iots.string, nullAsUndefined])
Many of my "strings" on the models are OptionalString
since I want deserialization of a missing attribute to be undefined
instead of null
.
I need the empty string -> undefined for POST, but I also need empty string -> null for PATCH.
Pretty standard entity like this:
export const Foo = iots.interface({
id: UUID,
name: iots.string,
description: iots.union([iots.string, iots.undefined]),
created: DateFromISOString,
updated: DateFromISOString
})
export type Foo = iots.TypeOf<typeof Foo>
export interface FooPatch {
name?: string;
description?: string;
}
export const toFooPatch = (current: Foo, toUpdate: Foo): FooPatch => ({
name: current.name === toUpdate.name ? undefined : toUpdate.name,
description: current.description === toUpdate.description ? undefined : toUpdate.description
})
The JSON PATCH for an empty string for description from the UI should result look like:
{
"description": null
}
instead of:
{
"description": ""
}
I think mapToOutput
is what I want. First pass, this looks like it is working how I want:
const emptyStringToUndefined = (s?: string): string | undefined => s?.trim()?.length === 0 ? undefined : s
const emptyStringToNull = (s?: string): string | null | undefined =>
s === undefined ? undefined : s?.trim()?.length === 0 ? null : s
export const EmptyStringAsUndefined = mapOutput(iots.string, emptyStringToUndefined)
export type EmptyStringAsUndefined = iots.TypeOf<typeof EmptyStringAsUndefined>
export const EmptyStringAsNull = mapOutput(iots.string, emptyStringToNull)
export type EmptyStringAsNull = iots.TypeOf<typeof EmptyStringAsNull>
Is there a simple extension, or do I need a completely new type?