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

Question: Convert a form to a type with different structure #710

Open
Massolari opened this issue Feb 27, 2024 · 0 comments
Open

Question: Convert a form to a type with different structure #710

Massolari opened this issue Feb 27, 2024 · 0 comments

Comments

@Massolari
Copy link

Massolari commented Feb 27, 2024

❓ Question

My current understanding

After reading the documentation, I understood that we can use Decoder.struct to convert a Form to, I could say, a FormValidated as below:

import * as D from "io-ts/Decoder"

type Form = {
  foo: string
  bar: number
}

type FormValidated = {
  foo: NonEmptyString
  bar: 0 | 1
}

const formDecoder = D.struct({
  foo: /* Decoder to parse it */,
  bar: /* Decoder to parse it */
})

Desired Behavior

My question is if there is a way to do the same thing for a type with a different structure. It's common here in the project I work on that we have a type that the backend expects and its structure isn't the same as the form. For example, can I convert Form to MyType in this example:

type Form = {
  foo: string
  bar: number
}

type MyType = {
  foobar: NonEmptyString
  barbaz: 0 | 1
}

I see that I can use Decoder.struct to parse the form to an intermediary type (this would be the FormValidated) and then use Decoder.map to construct MyType, but is there a way to do that directly?

Suggested Solution

I implemented a function to achieve that, the way I use it is:

import * as D from "io-ts/Decoder"
import * as DH from "./decoder-helper"

type Form = {
  foo: string
  bar: number
}

type MyType = {
  foobar: NonEmptyString
  barbaz: 0 | 1
}

const formDecoder = DH.top<Form, MyType>({
  foobar: DH.lift("foo", /* Decoder to parse it */),
  barbaz: DH.lift("bar", /* Decoder to parse it */)
})

This way I can convert Form directly to MyType without needing to convert it to an intermediary type.

My function is a bit complex, that's why I'm asking if there is already a way to do that.

Who does this impact? Who is this for?

This would benefit everyone that is using this library as a form decoder or even to decode JSON that has a different structure than the target type

Describe alternatives you've considered

Decoder.struct + Decoder.map

Additional context

I was inspired by this elm package

Your environment

Software Version(s)
io-ts ^2.2.21
fp-ts ^2.12.1
TypeScript ^5.1
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

1 participant