Nested Transformation of Objects/Arrays

What is the proper way to do a nested transformation like the following? I have data from an API (I don't control this API) that I want to convert from some other case (pascal, snake, etc.) to camelcase. I got it working by doing what I did with ParseResult but I have no idea if that's correct, is there a simpler way to do this when the structure is nested like it is here?

import { ParseResult, Schema } from 'effect';

class AutocompleteThingRaw extends Schema.Class<AutocompleteThingRaw>('AutocompleteThing')({
  some_thing: Schema.Number,
}) {}

class AutocompleteThingCamelCase extends Schema.Class<AutocompleteThingCamelCase>('AutocompleteThingCamelCase')({
  someThing: Schema.Number,
}) {}

const AutocompleteThing = Schema.transform(AutocompleteThingRaw, AutocompleteThingCamelCase, {
  decode: (raw) => ({
    someThing: raw.some_thing,
  }),
  encode: (camel) => ({
    some_thing: camel.someThing,
  }),
  strict: true,
});

class AutocompleteSuggestionsRaw extends Schema.Class<AutocompleteSuggestionsRaw>('AutocompleteSuggestionsRaw')({
  Autocomplete: Schema.Array(AutocompleteThingRaw),
}) {}

class AutocompleteSuggestionsCamelCase extends Schema.Class<AutocompleteSuggestionsCamelCase>(
  'AutocompleteSuggestionsCamelCase',
)({
  autocomplete: Schema.Array(AutocompleteThingCamelCase),
}) {}

export const AutocompleteSuggestions = Schema.transform(AutocompleteSuggestionsRaw, AutocompleteSuggestionsCamelCase, {
  decode: (raw) => ({
    autocomplete: ParseResult.decodeSync(Schema.Array(AutocompleteThing))(raw.Autocomplete),
  }),
  encode: (camel) => ({
    Autocomplete: ParseResult.encodeSync(Schema.Array(AutocompleteThing))(camel.autocomplete),
  }),
  strict: true,
});
Was this page helpful?