Skip to content

Decoder.sum is not typesafe, What is recommended to use between Decoder.union and Decoder.sum? #523

@kpritam

Description

@kpritam

I have two doubts:

  1. Difference between Decoder.union and Decoder.sum

    • IsDecoder.sum optimized and should be used whenever possible?
  2. Decoder.sum is not typesafe

    • In second argument of sum, key of object can be different than the corresponding value
    • Fails at runtime, shown in following example
const CircleD = D.type({
  kind: D.literal('Circle'),
  radius: D.number
})

const SquareD = D.type({
  kind: D.literal('Square'),
  x: D.number
})

// note here, key 'Circle1' is not valid but does not issue compile time error
const ShapeD = D.sum('kind')({
  Circle1: CircleD,
  Square: SquareD
})

// fails at runtime
ShapeD.decode({
  kind: 'Circle',
  radius: 10
 })

Above issue can be resolved if signature of sum is changed to following:

import * as D from 'io-ts/lib/Decoder'

const sum = <T extends string>(tag: T) => <A>(
  members: { [K in keyof A]: Decoder<A[K] extends { [Key in T]: K } ? A[K] : never> }
): Decoder<A[keyof A]> => D.sum(tag)(members)

// fails to compile
sum('kind')({
  Circle1: CircleD,
  Square: SquareD
})

Happy to submit PR if this make sense.

Metadata

Metadata

Assignees

No one assigned

    Labels

    experimentalsomething related to the experimental features

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions