Effect CommunityEC
Effect Community2y ago
23 replies
xaad

Trouble Using Custom Transform in Schema with Option/OptionEncoded

I am struggling to understand how to encode/decode optional fields to Options when using custom transform. At first, it looked straightforward but then I get a OptionEncoded type on which I cannot use the common Option functions (map, match...).

import * as S from '@effect/schema/Schema';
import * as Option from 'effect/Option';

// What my API need
const apiStruct = S.Struct({
  id: S.Number,
  fields: S.Struct({
    assignee: S.optional(S.Struct({ displayName: S.String }), { as: 'Option' }),
  }),
});

// What I would like to use in my app
const appStruct = S.Struct({
  id: S.Number,
  assignee: S.Option(S.String),
});

const transformSchema = S.transform(apiStruct, appStruct, {
  decode: ({ id, fields: { assignee: assigneeOpt } }) => ({
    // assigneeOpt is an Option<string>
    id,
    assignee: Option.map(assigneeOpt, (a) => a.displayName),
  }),
  encode: ({ id, assignee: assigneeOpt }) => ({
    // assigneeOpt is an OptionEncoded ??
    id,
    fields: Option.match(assigneeOpt, {
      onNone: () => ({}),
      onSome: (a) => ({ assignee: { displayName: a } }),
    }),
  })
});

console.log(
  S.decode(transformSchema)({
    id: 123,
    fields: { assignee: { displayName: 'helen' } },
  }),
); // <-- ParseError

console.log(
  S.encode(transformSchema)({
    id: 123,
    assignee: Option.some('helen'),
  }),
); // <-- ParseError


Many thanks for the awesome work! As a long-time fp-ts fan, it is great to see the two projects merge and all the recent activity around effect!
Was this page helpful?