Skip to content

Instantly share code, notes, and snippets.

@zaetrik
Last active June 4, 2020 18:19
Show Gist options
  • Save zaetrik/7b4bd89e2a20e8c7061aa3b5adbccb15 to your computer and use it in GitHub Desktop.
Save zaetrik/7b4bd89e2a20e8c7061aa3b5adbccb15 to your computer and use it in GitHub Desktop.
monocle-ts composing modifiers
import { Lens } from "monocle-ts";
interface Street {
num: number;
name: string;
}
interface Address {
city: string;
street: Street;
}
interface Company {
name: string;
address: Address;
}
interface Employee {
name: string;
company: Company;
}
const employee: Employee = {
name: "john",
company: {
name: "awesome inc",
address: {
city: "london",
street: {
num: 23,
name: "high street"
}
}
}
};
const capitalize = (s: string): string =>
s.substring(0, 1).toUpperCase() + s.substring(1);
const company = Lens.fromProp<Employee>()("company");
const city = Lens.fromProp<Address>()("city");
const address = Lens.fromProp<Company>()("address");
const street = Lens.fromProp<Address>()("street");
const streetName = Lens.fromProp<Street>()("name");
const companyName = Lens.fromProp<Company>()("name");
const employeeName = Lens.fromProp<Employee>()("name");
const capitalizeStreetName = company
.compose(address)
.compose(street)
.compose(streetName)
.modify(capitalize);
const capitalizeCity = company
.compose(address)
.compose(city)
.modify(capitalize);
const capitalizeCompanyName = company.compose(companyName).modify(capitalize);
const capitalizeName = employeeName.modify(capitalize);
const compose = <F extends (x: any) => any>(...fns: Array<F>) => (
...[x]: Parameters<F>
): ReturnType<F> => fns.reduce((y, f) => f(y), x);
const composeModifiers = <T>(...modifiers: Array<(s: T) => T>) =>
compose<(s: T) => T>(...modifiers);
const capitalizeEmployee = composeModifiers<Employee>(
capitalizeName,
capitalizeCompanyName,
capitalizeStreetName,
capitalizeCity
);
console.log(capitalizeEmployee(employee));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment