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/