From c5ea9ed742ce6bb7315c4a0a256460edf058bbf2 Mon Sep 17 00:00:00 2001 From: ikatyang Date: Sun, 6 Aug 2017 23:03:42 +0800 Subject: [PATCH] feat(path): no regression from npm-ramda --- snapshots/path.ts | 2 +- snapshots/ramda-tests.ts | 2 +- tasks/mixins/path.d.ts | 38 +++++++++++++++++++++++++ tasks/utils/bind-mixin.ts | 24 ++++++++++++++++ tasks/utils/generate-file-content.ts | 16 +++++++++++ tests/__snapshots__/path.ts.snap | 2 +- tests/__snapshots__/ramda-tests.ts.snap | 2 +- 7 files changed, 82 insertions(+), 4 deletions(-) create mode 100644 tasks/mixins/path.d.ts create mode 100644 tasks/utils/bind-mixin.ts diff --git a/snapshots/path.ts b/snapshots/path.ts index 16f893b..b6d6b0f 100644 --- a/snapshots/path.ts +++ b/snapshots/path.ts @@ -19,5 +19,5 @@ R_path(path, object); // @dts-jest:pass -> any R_path(['a', 'b', 'c'])(a_1_b_2_c_3); -// @dts-jest:pass -> any +// @dts-jest:pass -> 1 | 2 | 3 R_path(['a', 'b', 'c'], a_1_b_2_c_3); diff --git a/snapshots/ramda-tests.ts b/snapshots/ramda-tests.ts index 3b36781..27545e2 100644 --- a/snapshots/ramda-tests.ts +++ b/snapshots/ramda-tests.ts @@ -2127,7 +2127,7 @@ import * as R from '../ramda/dist/index'; // @dts-jest:group path (() => { - // @dts-jest:pass -> any + // @dts-jest:pass -> number R.path(['a', 'b'], { a: { b: 2 } }); //=> 2 // @dts-jest:pass -> any R.path(['a', 'b'])({ a: { b: 2 } }); //=> 2 diff --git a/tasks/mixins/path.d.ts b/tasks/mixins/path.d.ts new file mode 100644 index 0000000..6d61e4f --- /dev/null +++ b/tasks/mixins/path.d.ts @@ -0,0 +1,38 @@ +// tslint:disable:prettier naming-convention + +// in-based +declare function path(path: [T1, T2], obj: {[K1 in T1]: {[K2 in T2]: TResult}}): TResult; +declare function path(path: [T1, T2, T3], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: TResult}}}): TResult; +declare function path(path: [T1, T2, T3, T4], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: TResult}}}}): TResult; +declare function path(path: [T1, T2, T3, T4, T5], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: {[K5 in T5]: TResult}}}}}): TResult; +declare function path(path: [T1, T2, T3, T4, T5, T6], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: {[K5 in T5]: {[K6 in T6]: TResult}}}}}}): TResult; +declare function path(path: [T1, T2, T3, T4, T5, T6, T7], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: {[K5 in T5]: {[K6 in T6]: {[K7 in T7]: TResult}}}}}}}): TResult; +declare function path(path: [T1, T2, T3, T4, T5, T6, T7, T8], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: {[K5 in T5]: {[K6 in T6]: {[K7 in T7]: {[K8 in T8]: TResult}}}}}}}}): TResult; +declare function path(path: [T1, T2, T3, T4, T5, T6, T7, T8, T9], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: {[K5 in T5]: {[K6 in T6]: {[K7 in T7]: {[K8 in T8]: {[K9 in T9]: TResult}}}}}}}}}): TResult; + +// Record-based +declare function path(path: [K1, K2], obj: Record>): TResult; +declare function path(path: [K1, K2, K3], obj: Record>>): TResult; +declare function path(path: [K1, K2, K3, K4], obj: Record>>>): TResult; +declare function path(path: [K1, K2, K3, K4, K5], obj: Record>>>>): TResult; +declare function path(path: [K1, K2, K3, K4, K5, K6], obj: Record>>>>>): TResult; +declare function path(path: [K1, K2, K3, K4, K5, K6, K7], obj: Record>>>>>>): TResult; +declare function path(path: [K1, K2, K3, K4, K5, K6, K7, K8], obj: Record>>>>>>>): TResult; +declare function path(path: [K1, K2, K3, K4, K5, K6, K7, K8, K9], obj: Record>>>>>>>>): TResult; + +// for each path length list all combinations of objects and homogeneous arrays... tuples not supported yet. + +declare function path(path: [T1], obj: {[K1 in T1]: TResult}): TResult; +declare function path(path: [T1], obj: TResult[]): TResult; +declare function path(path: [T1, T2], obj: {[K1 in T1]: {[K2 in T2]: TResult}}): TResult; +declare function path(path: [T1, T2], obj: {[K1 in T1]: TResult[]}): TResult; +declare function path(path: [T1, T2], obj: {[K2 in T2]: TResult}[]): TResult; +declare function path(path: [T1, T2], obj: TResult[][]): TResult; +declare function path(path: [T1, T2, T3], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: TResult}}}): TResult; +declare function path(path: [T1, T2, T3], obj: {[K1 in T1]: {[K2 in T2]: TResult[]}}): TResult; +declare function path(path: [T1, T2, T3], obj: {[K1 in T1]: {[K3 in T3]: TResult}[]}): TResult; +declare function path(path: [T1, T2, T3], obj: {[K1 in T1]: TResult[][]}): TResult; +declare function path(path: [T1, T2, T3], obj: {[K2 in T2]: {[K3 in T3]: TResult}}[]): TResult; +declare function path(path: [T1, T2, T3], obj: {[K2 in T2]: TResult[]}[]): TResult; +declare function path(path: [T1, T2, T3], obj: {[K3 in T3]: TResult}[][]): TResult; +declare function path(path: [T1, T2, T3], obj: TResult[][][]): TResult; diff --git a/tasks/utils/bind-mixin.ts b/tasks/utils/bind-mixin.ts new file mode 100644 index 0000000..2ee3e12 --- /dev/null +++ b/tasks/utils/bind-mixin.ts @@ -0,0 +1,24 @@ +import * as dts from 'dts-element'; + +export const bind_mixin = ( + members: dts.ITopLevelMember[], + function_types: dts.IFunctionType[], +) => { + const main_type_declaration = members.find( + dts.is_type_declaration, + ) as dts.ITypeDeclaration; + + const type = main_type_declaration.type as dts.IObjectType; + type.members!.splice( + 1, + 0, + ...function_types.map(function_type => + dts.create_object_member({ + owned: dts.create_function_declaration({ + name: undefined, + type: function_type, + }), + }), + ), + ); +}; diff --git a/tasks/utils/generate-file-content.ts b/tasks/utils/generate-file-content.ts index 90e9132..b04852d 100644 --- a/tasks/utils/generate-file-content.ts +++ b/tasks/utils/generate-file-content.ts @@ -7,6 +7,7 @@ import { placeholder_name_abbr, } from '../../templates/utils/constants'; import { bind_jsdoc } from './bind-jsdoc'; +import { bind_mixin } from './bind-mixin'; import { placeholder, selectable } from './constants'; export function generate_file_content(filename: string) { @@ -40,6 +41,21 @@ function get_top_level_members(filename: string): dts.ITopLevelMember[] { bind_member_jsdoc_and_add_export_equal(); } + if (function_name === 'path') { + bind_mixin( + members, + dts + .parse( + fs.readFileSync( + path.resolve(__dirname, '../mixins/path.d.ts'), + 'utf8', + ), + ) + .members.filter(dts.is_function_declaration) + .map(function_declaration => function_declaration.type!), + ); + } + return members; function bind_member_jsdoc_and_add_export_equal() { diff --git a/tests/__snapshots__/path.ts.snap b/tests/__snapshots__/path.ts.snap index 682bf8e..7f11219 100644 --- a/tests/__snapshots__/path.ts.snap +++ b/tests/__snapshots__/path.ts.snap @@ -2,7 +2,7 @@ exports[`R_path(['a', 'b', 'c'])(a_1_b_2_c_3) 1`] = `"any"`; -exports[`R_path(['a', 'b', 'c'], a_1_b_2_c_3) 1`] = `"any"`; +exports[`R_path(['a', 'b', 'c'], a_1_b_2_c_3) 1`] = `"1 | 2 | 3"`; exports[`R_path(path) 1`] = `"(object: {}) => any"`; diff --git a/tests/__snapshots__/ramda-tests.ts.snap b/tests/__snapshots__/ramda-tests.ts.snap index 27b82e2..bfda1b1 100644 --- a/tests/__snapshots__/ramda-tests.ts.snap +++ b/tests/__snapshots__/ramda-tests.ts.snap @@ -995,7 +995,7 @@ exports[`partition R.partition(R.contains('s'), { a: 'sss', b: 'ttt', foo: 'bars exports[`path R.path(['a', 'b'])({ a: { b: 2 } }) 1`] = `"any"`; -exports[`path R.path(['a', 'b'], { a: { b: 2 } }) 1`] = `"any"`; +exports[`path R.path(['a', 'b'], { a: { b: 2 } }) 1`] = `"number"`; exports[`pathEq R.filter(isFamous, users) 1`] = `"User[]"`;