Skip to content

Instantly share code, notes, and snippets.

@dmmulroy
Last active March 22, 2024 21:04
Show Gist options
  • Save dmmulroy/0da10fe7768ebffc7657e2cb6a9e43fa to your computer and use it in GitHub Desktop.
Save dmmulroy/0da10fe7768ebffc7657e2cb6a9e43fa to your computer and use it in GitHub Desktop.
pure ts module based programming example
// Your module (i.e. file is for providing and working with one main type)
export type FooBar = {
foo: string;
bar: number;
then: (fn: (foobar: FooBar) => FooBar) => FooBar;
map: <T>(fn: (foobar: FooBar) => T) => T;
};
function make({ foo = "", bar = 0 }: Readonly<{ foo?: string; bar?: number }>) {
const foobar: FooBar = {
foo,
bar,
then: function (fn: (fb: FooBar) => FooBar): FooBar {
return fn(this);
},
map: function <T>(fn: (fb: FooBar) => T): T {
return fn(this);
},
};
return foobar;
}
function upperCaseFoo({ foo, bar }: FooBar): FooBar {
return make({ foo: foo.toUpperCase(), bar });
}
function doubleBar({ foo, bar }: FooBar): FooBar {
return make({ foo, bar: bar * 2 });
}
function toToml(foobar: FooBar): string {
return `
[foobar]
foo = ${foobar.foo}
bar = ${foobar.bar}
`;
}
function then(foobar: FooBar, fn: (_: FooBar) => FooBar): FooBar {
return fn(foobar);
}
function map<T>(foobar: FooBar, fn: (_: FooBar) => T): T {
return fn(foobar);
}
// You export an object of functions to operate on that one type
export const FooBar = {
doubleBar,
make,
map,
then,
toToml,
upperCaseFoo,
} as const;
import { FooBar } from "./foobar";
// We can use the export as a type and Module to operate on the type
const foobar: FooBar = FooBar.make({ foo: "foo", bar: 10 });
const foobarToml = foobar
.then(FooBar.doubleBar)
.then(FooBar.upperCaseFoo)
// we can also use our own functions in `then` or `map`
.then(({ foo, bar }) => FooBar.make({ foo: `new foo + ${foo}`, bar }))
.map(FooBar.toToml);
console.log(foobarToml);
// outputs:
// [foobar]
// foo = new foo + FOO
// bar = 20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment