Skip to content

Commit

Permalink
feat(mergeDeepLeft/Right): apply type inference (#407)
Browse files Browse the repository at this point in the history
  • Loading branch information
ikatyang committed Aug 11, 2018
1 parent 6d5b6cc commit f36e9b6
Show file tree
Hide file tree
Showing 11 changed files with 61 additions and 27 deletions.
11 changes: 8 additions & 3 deletions snapshots/mergeDeepLeft.ts
Expand Up @@ -2,11 +2,16 @@ import * as R from '../ramda/dist/index';

declare const a_1: { a: 1 };
declare const b_2: { b: 2 };
declare const a_1_x_y_1: { a: 1; x: { y: 1 } };
declare const b_1_x_z_1: { b: 1; x: { z: 1 } };

// @dts-jest:pass:snap -> (right: object) => object
// @dts-jest:pass:snap -> <U extends object>(right: U) => { "0": Pick<U, Exclude<keyof U, "a">> & Pick<{ a: 1; }, Exclude<"a", keyof U>> & { [K in Extract<keyof U, "a">]: any[U[K] extends object ? { a: 1; }[K] extends object ? 0 : 1 : 1]; }; "1": { a: 1; }; }[U extends object ? 0 : 1]
R.mergeDeepLeft(a_1);

// @dts-jest:pass:snap -> object
// @dts-jest:pass:snap -> Pick<{ b: 2; }, "b"> & Pick<{ a: 1; }, "a"> & {}
R.mergeDeepLeft(a_1)(b_2);
// @dts-jest:pass:snap -> object
// @dts-jest:pass:snap -> Pick<{ b: 2; }, "b"> & Pick<{ a: 1; }, "a"> & {}
R.mergeDeepLeft(a_1, b_2);

// @dts-jest:pass:snap -> Pick<{ b: 1; x: { z: 1; }; }, "b"> & Pick<{ a: 1; x: { y: 1; }; }, "a"> & { x: Pick<{ z: 1; }, "z"> & Pick<{ y: 1; }, "y"> & any; }
R.mergeDeepLeft(a_1_x_y_1, b_1_x_z_1);
11 changes: 8 additions & 3 deletions snapshots/mergeDeepRight.ts
Expand Up @@ -2,11 +2,16 @@ import * as R from '../ramda/dist/index';

declare const a_1: { a: 1 };
declare const b_2: { b: 2 };
declare const a_1_x_y_1: { a: 1; x: { y: 1 } };
declare const b_1_x_z_1: { b: 1; x: { z: 1 } };

// @dts-jest:pass:snap -> (right: object) => object
// @dts-jest:pass:snap -> <U extends object>(right: U) => { "0": Pick<{ a: 1; }, Exclude<"a", keyof U>> & Pick<U, Exclude<keyof U, "a">> & { [K in Extract<"a", keyof U>]: any[{ a: 1; }[K] extends object ? U[K] extends object ? 0 : 1 : 1]; }; "1": U; }[U extends object ? 0 : 1]
R.mergeDeepRight(a_1);

// @dts-jest:pass:snap -> object
// @dts-jest:pass:snap -> Pick<{ a: 1; }, "a"> & Pick<{ b: 2; }, "b"> & {}
R.mergeDeepRight(a_1)(b_2);
// @dts-jest:pass:snap -> object
// @dts-jest:pass:snap -> Pick<{ a: 1; }, "a"> & Pick<{ b: 2; }, "b"> & {}
R.mergeDeepRight(a_1, b_2);

// @dts-jest:pass:snap -> Pick<{ a: 1; x: { y: 1; }; }, "a"> & Pick<{ b: 1; x: { z: 1; }; }, "b"> & { x: Pick<{ y: 1; }, "y"> & Pick<{ z: 1; }, "z"> & any; }
R.mergeDeepRight(a_1_x_y_1, b_1_x_z_1);
4 changes: 2 additions & 2 deletions snapshots/ramda-tests.ts
Expand Up @@ -1858,7 +1858,7 @@ import * as R from '../ramda/dist/index';

// @dts-jest:group mergeDeepLeft
(() => {
// @dts-jest:pass:snap -> object
// @dts-jest:pass:snap -> Pick<{ age: number; contact: { email: string; }; }, never> & Pick<{ name: string; age: number; contact: { email: string; }; }, "name"> & { age: number; contact: Pick<{ email: string; }, never> & Pick<{ email: string; }, never> & any; }
R.mergeDeepLeft(
{ name: 'fred', age: 10, contact: { email: 'moo@example.com' } },
{ age: 40, contact: { email: 'baa@example.com' } },
Expand All @@ -1867,7 +1867,7 @@ import * as R from '../ramda/dist/index';

// @dts-jest:group mergeDeepRight
(() => {
// @dts-jest:pass:snap -> object
// @dts-jest:pass:snap -> Pick<{ name: string; age: number; contact: { email: string; }; }, "name"> & Pick<{ age: number; contact: { email: string; }; }, never> & { age: number; contact: Pick<{ email: string; }, never> & Pick<{ email: string; }, never> & any; }
R.mergeDeepRight(
{ name: 'fred', age: 10, contact: { email: 'moo@example.com' } },
{ age: 40, contact: { email: 'baa@example.com' } },
Expand Down
18 changes: 9 additions & 9 deletions templates/$operation.d.ts
Expand Up @@ -5,17 +5,17 @@ export type DeepPartial<T> = { [K in keyof T]?: DeepPartial<T[K]> };
// from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/f8fb828/types/ramda/index.d.ts#L64
export type Evolver<T> = Morphism<T, T> | { [K in keyof T]?: Evolver<T[K]> };

// from https://github.com/Microsoft/TypeScript/issues/12215#issuecomment-311923766
export type Diff<T extends PropKey, U extends PropKey> = ({ [P in T]: P } &
{ [P in U]: never } & { [x: string]: never })[T];
export type Omit<T, K extends PropKey> = Pick<T, Diff<keyof T, K>>;

export type Same<T extends PropKey, U extends PropKey> = Diff<
T | U,
Diff<T, U> | Diff<U, T>
>;
export type Omit<T, K extends PropKey> = Pick<T, Exclude<keyof T, K>>;
export type Same<T extends PropKey, U extends PropKey> = Extract<T, U>;
export type Merge<T, U> = Omit<T, keyof U> & U;

export type DeepMerge<T, U> = {
0: Omit<T, keyof U> &
Omit<U, keyof T> &
{ [K in Same<keyof T, keyof U>]: DeepMerge<T[K], U[K]> };
1: U;
}[T extends object ? (U extends object ? 0 : 1) : 1];

export interface NumberStringMap {
0: '0';
1: '1';
Expand Down
7 changes: 6 additions & 1 deletion templates/mergeDeepLeft.d.ts
@@ -1 +1,6 @@
export function $(left: object, right: object): object;
import { DeepMerge } from './$operation';

export function $<T extends object, U extends object>(
left: T,
right: U,
): DeepMerge<U, T>;
7 changes: 6 additions & 1 deletion templates/mergeDeepRight.d.ts
@@ -1 +1,6 @@
export function $(left: object, right: object): object;
import { DeepMerge } from './$operation';

export function $<T extends object, U extends object>(
left: T,
right: U,
): DeepMerge<T, U>;
8 changes: 5 additions & 3 deletions tests/__snapshots__/mergeDeepLeft.ts.snap
@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`R.mergeDeepLeft(a_1) 1`] = `"(right: object) => object"`;
exports[`R.mergeDeepLeft(a_1) 1`] = `"<U extends object>(right: U) => { \\"0\\": Pick<U, Exclude<keyof U, \\"a\\">> & Pick<{ a: 1; }, Exclude<\\"a\\", keyof U>> & { [K in Extract<keyof U, \\"a\\">]: any[U[K] extends object ? { a: 1; }[K] extends object ? 0 : 1 : 1]; }; \\"1\\": { a: 1; }; }[U extends object ? 0 : 1]"`;
exports[`R.mergeDeepLeft(a_1)(b_2) 1`] = `"object"`;
exports[`R.mergeDeepLeft(a_1)(b_2) 1`] = `"Pick<{ b: 2; }, \\"b\\"> & Pick<{ a: 1; }, \\"a\\"> & {}"`;
exports[`R.mergeDeepLeft(a_1, b_2) 1`] = `"object"`;
exports[`R.mergeDeepLeft(a_1, b_2) 1`] = `"Pick<{ b: 2; }, \\"b\\"> & Pick<{ a: 1; }, \\"a\\"> & {}"`;
exports[`R.mergeDeepLeft(a_1_x_y_1, b_1_x_z_1) 1`] = `"Pick<{ b: 1; x: { z: 1; }; }, \\"b\\"> & Pick<{ a: 1; x: { y: 1; }; }, \\"a\\"> & { x: Pick<{ z: 1; }, \\"z\\"> & Pick<{ y: 1; }, \\"y\\"> & any; }"`;
8 changes: 5 additions & 3 deletions tests/__snapshots__/mergeDeepRight.ts.snap
@@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`R.mergeDeepRight(a_1) 1`] = `"(right: object) => object"`;
exports[`R.mergeDeepRight(a_1) 1`] = `"<U extends object>(right: U) => { \\"0\\": Pick<{ a: 1; }, Exclude<\\"a\\", keyof U>> & Pick<U, Exclude<keyof U, \\"a\\">> & { [K in Extract<\\"a\\", keyof U>]: any[{ a: 1; }[K] extends object ? U[K] extends object ? 0 : 1 : 1]; }; \\"1\\": U; }[U extends object ? 0 : 1]"`;
exports[`R.mergeDeepRight(a_1)(b_2) 1`] = `"object"`;
exports[`R.mergeDeepRight(a_1)(b_2) 1`] = `"Pick<{ a: 1; }, \\"a\\"> & Pick<{ b: 2; }, \\"b\\"> & {}"`;
exports[`R.mergeDeepRight(a_1, b_2) 1`] = `"object"`;
exports[`R.mergeDeepRight(a_1, b_2) 1`] = `"Pick<{ a: 1; }, \\"a\\"> & Pick<{ b: 2; }, \\"b\\"> & {}"`;
exports[`R.mergeDeepRight(a_1_x_y_1, b_1_x_z_1) 1`] = `"Pick<{ a: 1; x: { y: 1; }; }, \\"a\\"> & Pick<{ b: 1; x: { z: 1; }; }, \\"b\\"> & { x: Pick<{ y: 1; }, \\"y\\"> & Pick<{ z: 1; }, \\"z\\"> & any; }"`;
4 changes: 2 additions & 2 deletions tests/__snapshots__/ramda-tests.ts.snap
Expand Up @@ -874,12 +874,12 @@ exports[`mergeAll R.mergeAll([{ foo: 1 }, { foo: 2 }, { bar: 2 }]) 1`] = `"objec
exports[`mergeDeepLeft R.mergeDeepLeft(
{ name: 'fred', age: 10, contact: { email: 'moo@example.com' } },
{ age: 40, contact: { email: 'baa@example.com' } },
) 1`] = `"object"`;
) 1`] = `"Pick<{ age: number; contact: { email: string; }; }, never> & Pick<{ name: string; age: number; contact: { email: string; }; }, \\"name\\"> & { age: number; contact: Pick<{ email: string; }, never> & Pick<{ email: string; }, never> & any; }"`;
exports[`mergeDeepRight R.mergeDeepRight(
{ name: 'fred', age: 10, contact: { email: 'moo@example.com' } },
{ age: 40, contact: { email: 'baa@example.com' } },
) 1`] = `"object"`;
) 1`] = `"Pick<{ name: string; age: number; contact: { email: string; }; }, \\"name\\"> & Pick<{ age: number; contact: { email: string; }; }, never> & { age: number; contact: Pick<{ email: string; }, never> & Pick<{ email: string; }, never> & any; }"`;
exports[`mergeDeepWith R.mergeDeepWith(
R.concat,
Expand Down
5 changes: 5 additions & 0 deletions tests/mergeDeepLeft.ts
Expand Up @@ -2,6 +2,8 @@ import * as R from '../ramda/dist/index';

declare const a_1: { a: 1 };
declare const b_2: { b: 2 };
declare const a_1_x_y_1: { a: 1; x: { y: 1 } };
declare const b_1_x_z_1: { b: 1; x: { z: 1 } };

// @dts-jest:pass:snap
R.mergeDeepLeft(a_1);
Expand All @@ -10,3 +12,6 @@ R.mergeDeepLeft(a_1);
R.mergeDeepLeft(a_1)(b_2);
// @dts-jest:pass:snap
R.mergeDeepLeft(a_1, b_2);

// @dts-jest:pass:snap
R.mergeDeepLeft(a_1_x_y_1, b_1_x_z_1);
5 changes: 5 additions & 0 deletions tests/mergeDeepRight.ts
Expand Up @@ -2,6 +2,8 @@ import * as R from '../ramda/dist/index';

declare const a_1: { a: 1 };
declare const b_2: { b: 2 };
declare const a_1_x_y_1: { a: 1; x: { y: 1 } };
declare const b_1_x_z_1: { b: 1; x: { z: 1 } };

// @dts-jest:pass:snap
R.mergeDeepRight(a_1);
Expand All @@ -10,3 +12,6 @@ R.mergeDeepRight(a_1);
R.mergeDeepRight(a_1)(b_2);
// @dts-jest:pass:snap
R.mergeDeepRight(a_1, b_2);

// @dts-jest:pass:snap
R.mergeDeepRight(a_1_x_y_1, b_1_x_z_1);

0 comments on commit f36e9b6

Please sign in to comment.