Skip to content

Commit

Permalink
path: enable inference, courtesy of #119. currently only does objects…
Browse files Browse the repository at this point in the history
…, not arrays.
  • Loading branch information
KiaraGrouwstra committed Dec 11, 2016
1 parent 3b05bd1 commit 8d28877
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
13 changes: 13 additions & 0 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1627,8 +1627,21 @@ declare namespace R {
/**
* Retrieve the value at a given path.
*/

// fixed-length versions, can calculate result but not yet able to deal with arrays, only objects so far...
path<T1 extends string, T2 extends string, TResult>(path: [T1, T2], obj: {[K1 in T1]: {[K2 in T2]: TResult}}): TResult;
path<T1 extends string, T2 extends string, T3 extends string, TResult>(path: [T1, T2, T3], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: TResult}}}): TResult;
path<T1 extends string, T2 extends string, T3 extends string, T4 extends string, TResult>(path: [T1, T2, T3, T4], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: TResult}}}}): TResult;
path<T1 extends string, T2 extends string, T3 extends string, T4 extends string, T5 extends string, TResult>(path: [T1, T2, T3, T4, T5], obj: {[K1 in T1]: {[K2 in T2]: {[K3 in T3]: {[K4 in T4]: {[K5 in T5]: TResult}}}}}): TResult;
path<T1 extends string, T2 extends string, T3 extends string, T4 extends string, T5 extends string, T6 extends string, TResult>(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;
path<T1 extends string, T2 extends string, T3 extends string, T4 extends string, T5 extends string, T6 extends string, T7 extends string, TResult>(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;
path<T1 extends string, T2 extends string, T3 extends string, T4 extends string, T5 extends string, T6 extends string, T7 extends string, T8 extends string, TResult>(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;
path<T1 extends string, T2 extends string, T3 extends string, T4 extends string, T5 extends string, T6 extends string, T7 extends string, T8 extends string, T9 extends string, TResult>(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;

// fallback, prevents errors but lacks inference; expected result must be supplied manually.
path<T>(path: Path, obj: Struct<any>): T;
path(path: Path): <T>(obj: Struct<any>) => T;

// path<T>: CurriedFn2<Path, Struct<any>, T>;
// failed attempt at proper typing, see https://github.com/Microsoft/TypeScript/issues/12393 :
// path<U, K1 extends keyof T, K2 extends keyof T[K1], T extends { [K1]: { [K2]: U } }>(keys: [K1, K2], obj: T): U;
Expand Down
8 changes: 8 additions & 0 deletions scripts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,11 @@ function liftNDefSeparate(i) {
}
R.flatten(R.range(2,10).map(i => liftNDefSeparate(i))).join('\r\n');

function pathDef(i) {
let obj = R.range(1,i+1).reduce((str, n) => `{[K${i-n+1} in T${i-n+1}]: ${str}}`, 'TResult');
let types = nm(i, n => `T${n+1}`);
let typesStr = nm(i, n => `T${n+1} extends string`);
return `path<${typesStr}, TResult>(path: [${types}], obj: ${obj}): TResult;`
}
R.flatten(R.range(2,10).map(i => pathDef(i))).join('\r\n')

12 changes: 12 additions & 0 deletions test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2238,4 +2238,16 @@ class Why {
let numbers: number[] = R.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]);
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
}
() => {
// #119: path
let pathArr: <T1 extends string, T2 extends number, T3 extends string, TResult>(path: [T1, T2, T3], obj: { [K1 in T1]: {[K2 in T2]: {[K3 in T3]: TResult } } }) => TResult;
let a1 = R.path(['a', 'b', 'c'], {a: {b: {c: 2}}}) // ok, objects only
let a2 = R.path(['a', 'b', 'c'], {a: {b: 2}}) // ok, granular def correctly fails, no c
let a3 = R.path(['a', '0', 'c'], {a: [{c: 2}] }) // granular def fails, can't deal with arrays yet
let a4 = R.path(['a', 0, 'c'], {a: [{c: 2}] }) // granular def fails, can't deal with arrays yet
let b3 = pathArr(['a', '0', 'c'], {a: [{c: 2}] }) // error
let b4 = pathArr(['a', 0, 'c'], {a: [{c: 2}] }) // error
}
*/

0 comments on commit 8d28877

Please sign in to comment.