Deep in Software with Hugo

Subscribe
Archives
July 29, 2025

Advanced TypeScript #1: enum to union

Welcome to the 97th Edition of the Code with Hugo newsletter.

What follows is 1/7 entries about TypeScript patterns I’ve encountered recently. You can find the examples repository at github.com/HugoDF/real-world-ts.

1. Enum to string union

TypeScript enums have a number of quirks and are not recommended for use, but a lot of existing systems use them.

The enum type is not the same as the union of the values of the enum, and this allows you to convert the enum to the union of values.

This patterns is useful for React component props, in that it avoids having to leak enum values. Eg. In your design system/UI library you dont want type={PrivateEnum.type} instead you want type="something" where something is in the PrivateEnum values.

import { expectTypeOf } from 'expect-type';

export enum TransactionTypes {
  CC = 'CC',
  BACS = 'BACS',
}

export type AsValue = `${TransactionTypes}`;

expectTypeOf<AsValue>().toEqualTypeOf<'CC' | 'BACS'>();

The difference in usage is that a field typed as TransactionTypes (the enum) will only accept values that are run through the TransactionTypes enum, whereas the AsValue converted string union will accept strings that are in the union.

function MyComp({ txType, txTypeStr }: { txType: TransactionTypes, txTypeStr: AsValue }) {
  //...
}
MyComp({ txType: TransactionTypes.CC, txTypeStr: 'CC' });
// @ts-expect-error Type '"CC"' is not assignable to type 'TransactionTypes'.
MyComp({ txType: 'CC', txTypeStr: TransactionTypes.CC });

That's this week's pattern, you can get a sneak peek of the rest at: https://codewithhugo.com/typescript-types-in-the-trenches/

Don't miss what's next. Subscribe to Deep in Software with Hugo:
GitHub Bluesky
Powered by Buttondown, the easiest way to start and grow your newsletter.