mirror of
https://github.com/gosticks/DefinitelyTyped.git
synced 2026-10-04 06:47:03 +00:00
Improve R.evolve typings
This commit is contained in:
Vendored
+25
-5
@@ -20,6 +20,7 @@
|
||||
// Keagan McClelland <https://github.com/CaptJakk>
|
||||
// Tomas Szabo <https://github.com/deftomat>
|
||||
// Bonggyun Lee <https://github.com/deptno>
|
||||
// Marcin Biernat <https://github.com/biern>
|
||||
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
|
||||
// TypeScript Version: 2.8
|
||||
|
||||
@@ -82,9 +83,28 @@ declare namespace R {
|
||||
(obj: Dictionary<T>): Dictionary<T>;
|
||||
}
|
||||
|
||||
type Evolver<T> =
|
||||
| ((x: T) => T)
|
||||
| { [K in keyof T]?: Evolver<T[K]> };
|
||||
type Evolve<O extends Evolvable<E>, E extends Evolver> = {
|
||||
[P in keyof O]: P extends keyof E ? EvolveValue<O[P], E[P]> : O[P];
|
||||
};
|
||||
|
||||
type EvolveValue<V, E> =
|
||||
E extends (value: V) => any ? ReturnType<E> :
|
||||
E extends Evolver ? EvolveNestedValue<V, E> :
|
||||
never;
|
||||
|
||||
type EvolveNestedValue<V, E extends Evolver> =
|
||||
V extends object ? (V extends Evolvable<E> ? Evolve<V, E> : never) : never;
|
||||
|
||||
interface Evolver {
|
||||
[key: string]: ((value: any) => any) | Evolver;
|
||||
}
|
||||
|
||||
// Represents all objects evolvable with Evolver E
|
||||
type Evolvable<E extends Evolver> = {
|
||||
[P in keyof E]?: E[P] extends (value: infer V) => any ? V :
|
||||
E[P] extends Evolver ? Evolvable<E[P]> :
|
||||
never
|
||||
};
|
||||
|
||||
// @see https://gist.github.com/donnut/fd56232da58d25ceecf1, comment by @albrow
|
||||
interface CurriedTypeGuard2<T1, T2, R extends T2> {
|
||||
@@ -604,8 +624,8 @@ declare namespace R {
|
||||
/**
|
||||
* Creates a new object by evolving a shallow copy of object, according to the transformation functions.
|
||||
*/
|
||||
evolve<V>(transformations: Evolver<V>, obj: V): V;
|
||||
evolve<V>(transformations: Evolver<V>): <W extends V>(obj: W) => W;
|
||||
evolve<E extends Evolver, V extends Evolvable<E>>(transformations: E, obj: V): Evolve<V, E>;
|
||||
evolve<E extends Evolver>(transformations: E): <V extends Evolvable<E>>(obj: V) => Evolve<V, E>;
|
||||
|
||||
/*
|
||||
* A function that always returns false. Any passed in parameters are ignored.
|
||||
|
||||
+48
-12
@@ -1307,19 +1307,55 @@ type Pair = KeyValuePair<string, number>;
|
||||
};
|
||||
|
||||
() => {
|
||||
const a1 = R.evolve({elapsed: R.add(1), remaining: R.add(-1)}, {name: "Tomato", elapsed: 100, remaining: 1400});
|
||||
const a2 = R.evolve({elapsed: R.add(1), remaining: R.add(-1)})({name: "Tomato", elapsed: 100, remaining: 1400});
|
||||
};
|
||||
// No type transformation
|
||||
|
||||
() => {
|
||||
// const tomato = {firstName: 'Tomato ', data: {elapsed: 100, remaining: 1400}, id:123};
|
||||
// const transformations = {
|
||||
// firstName: R.trim,
|
||||
// lastName: R.trim, // Will not get invoked.
|
||||
// data: {elapsed: R.add(1), remaining: R.add(-1)}
|
||||
// };
|
||||
// const a = R.evolve(transformations, tomato); // => {firstName: 'Tomato', data: {elapsed: 101, remaining: 1399}, id:123}
|
||||
// const b = R.evolve(transformations)(tomato); // => {firstName: 'Tomato', data: {elapsed: 101, remaining: 1399}, id:123}
|
||||
const a1 = R.evolve({ elapsed: R.add(1), remaining: R.add(-1) }, { name: "Tomato", elapsed: 100, remaining: 1400 });
|
||||
|
||||
const a1Test: { elapsed: number, remaining: number, name: string } = a1;
|
||||
|
||||
const a2 = R.evolve({ elapsed: R.add(1), remaining: R.add(-1) })({ name: "Tomato", elapsed: 100, remaining: 1400 });
|
||||
|
||||
const a2Test: { elapsed: number, remaining: number, name: string } = a2;
|
||||
|
||||
// Object doesn't have all evolver keys
|
||||
|
||||
const a3 = R.evolve({ age: R.add(1), name: R.trim }, { name: "Potato", elapsed: 100 });
|
||||
|
||||
const a3Test: { name: string, elapsed: number } = a3;
|
||||
|
||||
// Flat transformation
|
||||
|
||||
const ex0 = R.evolve({ a: parseInt }, { a: '10', b: 1 });
|
||||
|
||||
const ex0Test: { a: number, b: number } = ex0;
|
||||
|
||||
// Nested transformation:
|
||||
|
||||
const ex1 = R.evolve(
|
||||
{ a: { b: R.toString, d: { e: R.toString } } },
|
||||
{ a: { b: 1, c: null, d: { e: 2 } } },
|
||||
);
|
||||
|
||||
const ex1Test: { a: { b: string, c: null, d: { e: string } } } = ex1;
|
||||
|
||||
// Mapping a nested object with a single function
|
||||
|
||||
const ex2 = R.evolve(
|
||||
{ a: (obj: { foo: string }) => ({ bar: 1, baz: 2 }) },
|
||||
{ a: { foo: 'a', skipped: 3 }, b: null },
|
||||
);
|
||||
|
||||
const ex2Test: { a: { bar: number, baz: number }, b: null } = ex2;
|
||||
|
||||
// Nested curried:
|
||||
|
||||
const ex3 = R.evolve(
|
||||
{ a: { b: R.toString, d: { e: R.toString } } },
|
||||
)(
|
||||
{ a: { b: 1, c: null, d: { e: 2 } } }
|
||||
);
|
||||
|
||||
const ex3Test: { a: { b: string, c: null, d: { e: string } } } = ex3;
|
||||
};
|
||||
|
||||
() => {
|
||||
|
||||
Reference in New Issue
Block a user