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

Default values #8

Closed
gyzerok opened this issue Feb 10, 2017 · 7 comments
Closed

Default values #8

gyzerok opened this issue Feb 10, 2017 · 7 comments

Comments

@gyzerok
Copy link

gyzerok commented Feb 10, 2017

What do you think about having an ability to define default value. So if value is null or undefined it is got swapped with the value provided.

t.fromValidation(null, t.withDefault(t.string, 'hello world')) // 'hello world'
@gcanti
Copy link
Owner

gcanti commented Feb 10, 2017

I think that is already possible

function withDefault<T extends t.Any>(type: T, defaultValue: t.TypeOf<T>): t.Type<t.TypeOf<T>> {
  return new t.Type(
    type.name,
    (v, c) => type.validate(v != null ? v : defaultValue, c)
  )
}

@gyzerok
Copy link
Author

gyzerok commented Feb 13, 2017

Yeah, that make sense. I would try it as you described in my code and see if it's helpful. If it is, I guess we can discuss making it part of API.

@gyzerok gyzerok closed this as completed Feb 13, 2017
@gunzip
Copy link

gunzip commented Dec 22, 2017

while this worked for properties in partial types as well until 0.9.1, this does not validate / populate default values anymore in t.partial(s) because of some changes in 0.9.2. this was a breaking change for us :)

ref.

https://github.com/teamdigitale/digital-citizenship-functions/blob/tech-debt/lib/utils/default.ts
https://github.com/teamdigitale/digital-citizenship-functions/blob/tech-debt/lib/utils/__tests__/default.test.ts

@gyzerok gyzerok reopened this Dec 22, 2017
@gcanti
Copy link
Owner

gcanti commented Dec 22, 2017

@gunzip links are broken, could you please provide a test case?

@gcanti
Copy link
Owner

gcanti commented Dec 22, 2017

I think I got a repro

export function withDefault<T extends t.Any>(type: T, defaultValue: t.TypeOf<T>): t.Type<t.InputOf<T>, t.TypeOf<T>> {
  return new t.Type(
    `withDefault(${type.name}, ${JSON.stringify(defaultValue)})`,
    type.is,
    (v, c) => type.validate(v != null ? v : defaultValue, c),
    type.serialize
  )
}

const T1 = t.partial({
  name: withDefault(t.string, 'foo')
})

console.log(t.validate({}, T1).fold(() => 'error', a => JSON.stringify(a)))
// => `{}`

Related commit 37c74a5

My opinion is that it's better to give the passed type a chance to perform a deserialization and, in case of failure, fallback to undefinedType. I'll revert that change.

gcanti added a commit that referenced this issue Dec 22, 2017
@gcanti gcanti closed this as completed in ad69c2d Dec 23, 2017
gunzip added a commit to pagopa-archive/io-functions that referenced this issue Dec 23, 2017
@safareli
Copy link
Contributor

safareli commented Jul 7, 2021

This is the version for decoders that I use:

export function withDefault<T extends D.Decoder<unknown, unknown>>(
  decoder: T,
  defaultValue: D.TypeOf<T>
): D.Decoder<D.InputOf<T>, D.TypeOf<T>> {
  return D.union(
    decoder,
    pipe(
      undefinedDecoder,
      D.map(() => defaultValue)
    )
  );
}

export const undefinedDecoder = {
  decode: (val: unknown) => {
    return val === undefined
      ? D.success(undefined)
      : D.failure(val, "undefined");
  },
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants