Skip to content

Instantly share code, notes, and snippets.

@dplusic
Last active December 19, 2018 05:13
Show Gist options
  • Save dplusic/69ea5c3d072acf7a8fe58f1068f743d8 to your computer and use it in GitHub Desktop.
Save dplusic/69ea5c3d072acf7a8fe58f1068f743d8 to your computer and use it in GitHub Desktop.
Typescript Functional Mixin
interface Flying {
fly(): this;
isFlying: () => boolean;
land(): this;
}
const flying = <O>(o: O) : O & Flying => {
let isFlying = false;
return Object.assign({}, o, {
fly() {
isFlying = true;
return this;
},
isFlying: () => isFlying,
land() {
isFlying = false;
return this;
}
});
};
interface Quacking {
quack: () => string;
}
const quacking = (quack: string) => <O> (o: O) => Object.assign({}, o, {
quack: () => quack
});
const bird = flying({});
document.writeln(`${bird.isFlying()}`); // false
document.writeln(`${bird.fly().isFlying()}`); // true
const quacker = quacking('Quack!')({});
document.writeln(quacker.quack()); // 'Quack!'
const createDuck = (quack: string) => quacking(quack)(flying({}));
const duck = createDuck('Quack!');
document.writeln(duck.fly().quack()); // 'Quack!'
const merge = <A, B>(a: () => A, b: () => B) => (): A & B => {
return Object.assign({}, a(), b());
};
const Foo = <P>(P: () => P) => {
const p = P();
return (f: (p: P) => void) => () => f(p);
}
type P1 = { p1: string };
const P1 = (): P1 => ({ p1: 'p1' });
type P2 = { p2: string };
const P2 = (): P2 => ({ p2: 'p2' });
type P3 = { p3: string };
const P3 = (): P3 => ({ p3: 'p3' });
type PS1 = P1 & P2 & P3;
const PS1: (() => PS1) = merge(merge(P1, P2), P3);
const foo = Foo(PS1)(ps1 => {
document.writeln(ps1.p1);
document.writeln(ps1.p2);
document.writeln(ps1.p3);
});
foo();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment