Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support nullable type. #29

Closed
OzairP opened this issue Nov 20, 2018 · 3 comments
Closed

Support nullable type. #29

OzairP opened this issue Nov 20, 2018 · 3 comments

Comments

@OzairP
Copy link

OzairP commented Nov 20, 2018

interface User {
    user_id: number,
    nickname: string | null
}

export const UserDecoder: Decoder<User> = object({
    user_id: number(),
    nickname: nullable(string())
})

@mulias
Copy link
Contributor

mulias commented Nov 20, 2018

@OzairP I realize that I've provided optional but not nullable as a core decoder, which is inconsistent. Fortunately nullable is a pretty simple decoder to build from the existing combinators:

const nullabe = <T>(decoder: Decoder<T>): Decoder<T | null> =>
  union(decoder, constant(null));

My hope is that this library can act as a toolbox for you to make whatever decoders you need for your project. Do you think there's some part of the documentation that I could improve on to make examples like this more evident?

@mulias
Copy link
Contributor

mulias commented Nov 23, 2018

I originally assumed that you were looking for something equivalent to the Elm nullable decoder, but I happened to think of a slightly different use case that might be worth mentioning. I tend not to see explicit null values in JSON, but I do sometimes use field: FieldType | null instead of field?: FieldType in order to be more explicit. Here's how you could implement a decoder that returns null when a value isn't present in the input:

/**
 * Returns a `placeholder` value if the input is not found -- for example when a field is not
 * present in an object, or an array index is out of bounds. Unlike `withDefault`, the placeholder
 * is not returned if the input is found and fails to decode.
 */
const whenAbsent = <T, Q>(placeholder: T, decoder: Decoder<Q>): Decoder<T | Q> =>
  union(decoder, constant(undefined)).map((val) => val === undefined ? placeholder : val)

/**
 * Validates the given `decoder` or `null`. If the input is not found then decode to `null`.
 */
const nullable = <T>(decoder: Decoder<T>): Decoder<T | null> =>
  whenAbsent(null, union(decoder, constant(null)));

@mulias
Copy link
Contributor

mulias commented May 22, 2019

This issue is still under specified, #37 is a more productive line of conversation.

@mulias mulias closed this as completed May 22, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants