DEV Community

Cover image for I Did A Thing 👀 ... Full Article coming later today
Ja
Ja

Posted on

I Did A Thing 👀 ... Full Article coming later today

Your eyes aren't fooling you... I finally did it. Real discriminated unions in Typescript, with a couple of extra OO superpowers, and compile time error validation.

const UploadState = union({
  Initial: null,
  Pending: {
    Preparing: (fileName: string) => ({ fileName }),
    Uploading: (progress: number) => ({ progress }),
    Processing: (stage: string) => ({ stage })
  },
  Complete: (url: string) => ({ url }),
  Failed: (reason: string) => ({ reason })
});

// Usage
const upload = UploadState.Pending.Uploading(45);


// Many ways to destruct a union
const getUploadStatus = match(upload).to({
  Initial: () => "Ready to upload",
  Pending: (state) => state.match({
    Preparing: ({ fileName }) => `Preparing ${fileName}...`,
    Uploading: ({ progress }) => `Uploading: ${progress}%`,
    Processing: ({ stage }) => `Processing: ${stage}`
  }),
  Complete: ({ url }) => `Upload complete: ${url}`,
  Failed: ({ reason }) => `Upload failed: ${reason}`
});

//...or 

const getUploadStatus = match(upload).to({
  Initial: () => "Ready to upload",
  None: () => "I don't believe in 'Users'. What are those?"
});

//...or

const getUploadStatus = match.to<typeof UploadState>({
  //the type system complains when you don't exhaust all options
  Complete: ({ url }) => `Upload complete: ${url}`,
  Failed: ({ reason }) => `Upload failed: ${reason}`,
  None: () => `I got your load!` //use None as a catch all
})
Enter fullscreen mode Exit fullscreen mode

🎶 Do you believe in magic?

Image description

I know there are other libraries on the market. But none quite like this (although, technically, this is not a "library" just yet. But once I'm done this journey, I will publish and package this for everyone's consumption).

Stay tuned.

Top comments (1)

Collapse
 
jonesbeach profile image
Jones Beach

you are on a roll! looking forward to switching my entire Rust stack to your upcoming TS library