Skip to content

Commit

Permalink
everything else is borked BUT enum seems solid finally
Browse files Browse the repository at this point in the history
  • Loading branch information
oofdere committed Aug 13, 2024
1 parent 91a7849 commit 2d3de5b
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 11 deletions.
10 changes: 5 additions & 5 deletions examples/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ const red = pack("Red", 128) //=> const red: Enum<Colors>
const green = pack<Colors>("Green", 128) //=> const green: Enum<Colors>
const blue = pack<Colors>("Blue", 128) //=> const blue: Enum<Colors>

function toRGB(color: Enum<Colors>) { // returns number[]
match(color, {
Rgb: (x) => x, //=> (property) Rgb: (x: [number, number, number]) => [number, number, number]
function toRGB(color: Colors) { // returns number[]
const a = match(color, {
Rgb: (x) => x, //=>
_: (x) => x //=>
});
}); //=>

return match(color, {
const b = match(color, {
Red: (x) => [x, 0, 0], //=> (property) Red: (x: number) => number[]
Green: (x) => [0, x, 0], //=> (property) Green: (x: number) => number[]
Blue: (x) => [0, 0, x], //=> (property) Blue: (x: number) => number[]
Expand Down
42 changes: 36 additions & 6 deletions src/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,43 @@ type PartialArms<E> = {
};

// this is the recommended way to create enum instances so you have strong type checking
export const pack = <E>(...entry: EnumChecked<E>) => entry satisfies EnumChecked<E>;
export function pack<E>(...entry: Enum<E>) {
return entry as E // this is disgusting and we are completely just lying to tsc and the user and it works
}

export const match = <E, Fn extends Arms<E>>(
pattern: Enum<E>,
export function match<E, Fn extends Arms<E>>(
pattern: E,
arms: Fn,
): ReturnType<typeof arms[keyof typeof arms]> =>
): ReturnType<typeof arms[keyof typeof arms]> {
// ^ typescript ABSOLUTELY FREAKS OUT about this BUT it does work so ¯\_(ツ)_/¯
// biome-ignore lint/suspicious/noExplicitAny: return type is handled externally
((arms[pattern[0]] as any) || (arms as any)._)(pattern[1] as any);; // <- dunno why there are two semicolons here
// typescript REALLY hates this (hence all the `any`) and I really can't blame it
return ((arms[pattern[0]] as any) || (arms as any)._)(pattern[1] as any) as ReturnType<typeof arms[keyof typeof arms]>;
// typescript REALLY hates this (hence all the `any`) and I really can't blame it
}

type Color = {
Red: number;
Blue: number;
Green: number;
Rgb: [number, number, number];
};

const red = pack<Color>("Red", 128) //=> const red: Enum<Colors>
const green = pack<Color>("Green", 128) //=> const green: Enum<Colors>
const blue = pack<Color>("Blue", 128) //=> const blue: Enum<Colors>

function toRGB(color: Color) { // returns number[]
const a = match(color, {
Rgb: (x) => x, //=>
_: (x) => x //=>
}); //=>

const b = match(color, {
Red: (x) => [x, 0, 0], //=>
Green: (x) => [0, x, 0], //=>
Blue: (x) => [0, 0, x], //=>
Rgb: (x) => x //=>
});
}

console.log(toRGB(blue)); // [ 0, 0, 128 ]

0 comments on commit 2d3de5b

Please sign in to comment.