toggle.ts

 1import { DeepPartial } from 'utility-types';
 2import merge from 'ts-deepmerge';
 3
 4interface Toggleable<T> {
 5  inactive: T
 6  active: T,
 7}
 8
 9/// Helper function for creating Toggleable objects; it takes a object of type T that is used as
10/// `inactive` member of result Toggleable<T>. `active` member is created by applying `modifications` on top of `inactive` argument.
11// Thus, the following call:
12// ```
13//   toggleable({day: 1, month: "January"}, {day: 3})
14// ```
15// To return the following object:
16// ```
17//    Toggleable<_>{
18//      inactive: { day: 1, month: "January" },
19//      active: { day: 3, month: "January" }
20//    }
21// ```
22// Remarkably, it also works for nested structures:
23// ```
24//   toggleable({first_level: "foo", second_level: {nested_member: "nested"}}, {second_level: {nested_member: "another nested thing"}})
25// ```
26// ```
27//   Toggleable<_> {
28//     inactive: {first_level: "foo", second_level: {nested_member: "nested"}},
29//     active: { first_level: "foo", second_level: {nested_member: "another nested thing"}}
30//   }
31// ```
32export function toggleable<T extends Object>(inactive: T, modifications: DeepPartial<T>): Toggleable<T> {
33  let active: T = merge(inactive, modifications) as T;
34  return { active: active, inactive: inactive };
35}