first iterations of types

This commit is contained in:
Yanick Champoux 2019-01-18 19:46:25 -05:00
parent 26d87e24f6
commit facfac3ec5
20 changed files with 309 additions and 0 deletions

30
types/constant.d.ts vendored Normal file
View File

@ -0,0 +1,30 @@
/**
* Returns a function that always returns the supplied value.
*
* Useful for replacing an object outright rather than merging it.
*
* @memberOf u
*
* @example
* var alwaysFour = u.constant(4);
* expect(alwaysFour(32)).toEqual(4);
*
* @example
* var user = {
* name: 'Mitch',
* favorites: {
* band: 'Nirvana',
* movie: 'The Matrix'
* }
* };
*
* var newFavorites = {
* band: 'Coldplay'
* };
*
* var result = u({ favorites: u.constant(newFavorites) }, user);
*
* expect(result).toEqual({ name: 'Mitch', favorites: { band: 'Coldplay' } });
*/
export declare function constant<A>(value: A): (...args: any[]) => A;
export default constant;

12
types/freeze.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
/**
* Deeply freeze a plain javascript object.
*
* If `process.env.NODE_ENV === 'production'`, this returns the original object
* without freezing.
*
* Or if `process.env.UPDEEP_MODE === 'dangerously_never_freeze'`, this returns the original object
* without freezing.
*
*/
declare function freeze<O>(object: O): O;
export default freeze;

13
types/if.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
import { Predicate, MergedUpdate, TruePredicate, FalsePredicate } from './types';
export declare function uIf<TU, O>(predicate: FalsePredicate<O>, trueUpdates: TU, object: O): O;
export declare function uIf<TU, O>(predicate: TruePredicate<O>, trueUpdates: TU, object: O): MergedUpdate<TU, O>;
interface CurriedIf {
<TU, O>(predicate: TruePredicate<O>, trueUpdates: TU, object: O): MergedUpdate<TU, O>;
<TU, O>(predicate: FalsePredicate<O>, trueUpdates: TU, object: O): O;
<TU, O>(predicate: Predicate<O>, trueUpdates: TU, object: O): MergedUpdate<TU, O> | O;
<TU, O>(predicate: TruePredicate<O>, trueUpdates: TU): (object: O) => MergedUpdate<TU, O>;
<TU, O>(predicate: FalsePredicate<O>, trueUpdates: TU): (object: O) => O;
<TU, O>(predicate: Predicate<O>, trueUpdates: TU): (object: O) => MergedUpdate<TU, O> | O;
}
declare const _default: CurriedIf;
export default _default;

13
types/ifElse.d.ts vendored Normal file
View File

@ -0,0 +1,13 @@
import { Predicate, MergedUpdate, FalsePredicate, TruePredicate } from './types';
export declare function updateIfElse<S, TU, FU>(predicate: TruePredicate<S>, trueUpdates: TU, falseUpdates: FU, object: S): MergedUpdate<TU, S>;
export declare function updateIfElse<S, TU, FU>(predicate: FalsePredicate<S>, trueUpdates: TU, falseUpdates: FU, object: S): MergedUpdate<FU, S>;
interface CurriedIfElse {
<S, TU, FU>(predicate: TruePredicate<S>, trueUpdates: TU, falseUpdates: FU, object: S): MergedUpdate<TU, S>;
<S, TU, FU>(predicate: FalsePredicate<S>, trueUpdates: TU, falseUpdates: FU, object: S): MergedUpdate<FU, S>;
<S, TU, FU>(predicate: Predicate<S>, trueUpdates: TU, falseUpdates: FU, object: S): MergedUpdate<TU, S> | MergedUpdate<FU, S>;
<S, TU, FU>(predicate: TruePredicate<S>, trueUpdates: TU, falseUpdates: FU): (object: S) => MergedUpdate<TU, S>;
<S, TU, FU>(predicate: FalsePredicate<S>, trueUpdates: TU, falseUpdates: FU): (object: S) => MergedUpdate<FU, S>;
<S, TU, FU>(predicate: Predicate<S>, trueUpdates: TU, falseUpdates: FU): (object: S) => MergedUpdate<TU, S> | MergedUpdate<FU, S>;
}
declare const _default: CurriedIfElse;
export default _default;

30
types/index.d.ts vendored Normal file
View File

@ -0,0 +1,30 @@
import { constant } from './constant';
import freeze from './freeze';
import is from './is';
import _if from './if';
import ifElse from './ifElse';
import map from './map';
import omit from './omit';
import omitBy from './omitBy';
import reject from './reject';
import update, { omitted } from './update';
import updateIn from './updateIn';
import withDefault from './withDefault';
import { _ as placeholder } from './util/curry';
declare const u: {
omit: typeof omit;
omitBy: typeof omitBy;
constant: typeof constant;
freeze: typeof freeze;
is: typeof is;
update: typeof update;
updateIn: typeof updateIn;
reject: typeof reject;
map: typeof map;
withDefault: typeof withDefault;
ifElse: typeof ifElse;
if: typeof _if;
omitted: typeof omitted;
_: typeof placeholder;
} & typeof update;
export default u;

9
types/is.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
import { Path } from './types';
export declare function is(path: Path, predicate: any, object: any): boolean;
interface CurriedIs {
(path: Path, predicate: any, object: any): boolean;
(path: Path, predicate: any): (object: any) => boolean;
(path: Path): (predicate: any) => (object: any) => boolean;
}
declare const _default: CurriedIs;
export default _default;

11
types/map.d.ts vendored Normal file
View File

@ -0,0 +1,11 @@
import { MergedUpdate } from './types';
declare type Mapped<I, O extends object> = {
[K in keyof O]: MergedUpdate<I, O[K]>;
};
export declare function map<I, O extends object>(iteratee: I, object: O): Mapped<I, O>;
interface CurriedMap {
<I, O extends object>(iteratee: I, object: O): Mapped<I, O>;
<I, O extends object>(iteratee: I): (object: O) => Mapped<I, O>;
}
declare const _default: CurriedMap;
export default _default;

7
types/omit.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
export declare function omit(predicate: string[] | string, collection: object): object;
interface CurriedOmit {
(predicate: string[] | string, collection: object): object;
(predicate: string[] | string): (collection: object) => object;
}
declare const _default: CurriedOmit;
export default _default;

7
types/omitBy.d.ts vendored Normal file
View File

@ -0,0 +1,7 @@
export declare function omitBy<C extends object, P extends (...args: any[]) => boolean>(predicate: P, collection: C): object;
interface CurriedOmitBy {
<C extends object, P extends (...args: any[]) => boolean>(predicate: P, collection: C): object;
<C extends object, P extends (...args: any[]) => boolean>(predicate: P): (collection: C) => object;
}
declare const _default: CurriedOmitBy;
export default _default;

9
types/reject.d.ts vendored Normal file
View File

@ -0,0 +1,9 @@
export declare function reject<C extends object>(predicate: any, collection: C): C extends any[] ? C : object;
interface CurriedReject {
<C extends any[]>(predicate: any, collection: C): C;
<C extends object>(predicate: any, collection: C): Array<C[keyof C]>;
<C extends any[]>(predicate: any): (collection: C) => C;
<C extends object>(predicate: any): (collection: C) => Array<C[keyof C]>;
}
declare const _default: CurriedReject;
export default _default;

61
types/tests.ts Normal file
View File

@ -0,0 +1,61 @@
// TypeScript Version: 3.2.2
import u from "updeep";
u.omitted('whatever'); // $ExpectType { __omitted: boolean; }
const obj = { this: 3 };
u(true, obj); // $ExpectType true
u(null, obj); // $ExpectType null
u(undefined, obj); // $ExpectType undefined
u("a specific string", obj); // $ExpectType "a specific string"
u(true)(obj); // $ExpectType true
u(null)(obj); // $ExpectType null
u(undefined)(obj); // $ExpectType undefined
u("a specific string")(obj); // $ExpectType "a specific string"
const aString = "a" + "b";
u(aString, obj); // $ExpectType string
u((i: number) => "foo" + i, 1); // $ExpecType string
u((i: number) => "foo" + i, "bar");
// update is object
u({ this: 2 }, true); // $ExpectType UpdateReturnMap<{ this: number; }>
u({ this: 2 })(true); // $ExpectType UpdateReturnMap<{ this: number; }>
u({ this: 2 }, { this: 3 }); // $ExpectType object
u({ this: 2 })({ that: 3 }); // $ExpectType object
u({ this: 2 })(true); // UpdateReturnMap<{ this: number; }>
u({ this: 2 })({ that: 3 }); // $ExpectType object
u.ifElse(false as boolean, { a: 1 }, { a: 2 }, { a: 3 }); // $ExpectType object
u.ifElse(false as boolean, "foo", 3, { a: 3 }); // $ExpectType string | number
u.ifElse(false, "foo", 3, { a: 3 }); // $ExpectType number
u.ifElse(true, "foo", 3, { a: 3 }); // $ExpectType string
// *** map ***
const inc = (i:number) => i+1;
u.map(inc, [1,2,3]); // $ExpectType number[]
u.map(inc, ["potato"]); // $ExpectType number[]
u.map({a:1},{a:2}); // $ExpectType Mapped<{ a: number; }, { a: number; }>
u.omit('bar', { }); // $ExpectType object
u.omit(['bar'], { }); // $ExpectType object
u.omitBy([ 'banana' ], { } ); // $ExpectError
// *** constant ***
// $ExpectType { banana: number; }
u.constant({ banana: 1 })('foo');
/// *** freeze ***
// $ExpectType { potato: number; }
u.freeze({ potato: 1 });

14
types/tsconfig.json Normal file
View File

@ -0,0 +1,14 @@
{
"compilerOptions": {
"module": "commonjs",
"lib": ["es6"],
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"noEmit": true,
"baseUrl": "./",
"paths": { "updeep": ["."] }
}
}

11
types/tslint.json Normal file
View File

@ -0,0 +1,11 @@
{
"extends": "dtslint/dtslint.json",
"rules": {
"trim-file": false,
"no-consecutive-blank-lines": false,
"typedef-whitespace": false,
"whitespace": false,
"space-within-parens": false,
"prefer-declare-function": false,
"no-unnecessary-generics": false,
"strict-export-declare-modifiers": false } }

14
types/types.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
export declare type Updates = any;
export declare type Source = any;
export declare type PathPart = number | string;
export declare type Path = PathPart | PathPart[];
export declare type TruePredicate<S = any> = true | ((a: S) => true);
export declare type FalsePredicate<S = any> = false | ((a: S) => false);
export declare type Predicate<S = any> = boolean | ((arg: S) => boolean);
export declare type MergedUpdate<U, O> = O extends object ? (UpdateReturnType<U> extends object ? object : UpdateReturnType<U>) : UpdateReturnType<U>;
export declare type UpdateReturnMap<T> = {
[K in keyof T]: UpdateReturnType<T[K]>;
};
export declare type UpdateReturnType<U> = U extends (object: any) => any ? ReturnType<U> : U extends object ? UpdateReturnMap<U> : U;
export declare type ReturningFunction = (...args: any[]) => any;
export declare type ArgumentsType<F extends (...args: any[]) => any> = F extends (...args: infer A) => any ? A : never;

32
types/update.d.ts vendored Normal file
View File

@ -0,0 +1,32 @@
import { MergedUpdate, UpdateReturnType } from './types';
export declare const omitted: (...args: any[]) => {
__omitted: boolean;
};
/**
* Recursively update an object or array.
*
* Can update with values:
* update({ foo: 3 }, { foo: 1, bar: 2 });
* // => { foo: 3, bar: 2 }
*
* Or with a function:
* update({ foo: x => (x + 1) }, { foo: 2 });
* // => { foo: 3 }
*
*/
export declare function update<U>(updates: U extends object ? never : U, object: any): U;
export declare function update<U, O>(updates: U, object: O extends object ? never : O): UpdateReturnType<U>;
export declare function update<U, O>(updates: U, object: O, ...args: any[]): MergedUpdate<U, O>;
interface CurriedUpdate1<U> {
<O>(object: O extends object ? never : O): UpdateReturnType<U>;
<O>(object: O, ...args: any[]): MergedUpdate<U, O>;
}
interface CurriedUpdate {
<U>(updates: U extends object ? never : U, object: any): U;
<U, O>(updates: U, object: O extends object ? never : O): UpdateReturnType<U>;
<U, O>(updates: U, object: O, ...args: any[]): MergedUpdate<U, O>;
<U>(updates: U extends object ? never : U): (object: any) => U;
<U>(updates: U): CurriedUpdate1<U>;
}
declare const _default: CurriedUpdate;
export default _default;

12
types/updateIn.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
import { Path } from './types';
export declare function updateIn(path: Path, value: any, object: any): any;
interface Curry2 {
(value: any, object: any): any;
(value: any): (object: any) => any;
}
interface CurriedUpdateIn {
(path: Path, value: any, object: any): any;
(path: Path): Curry2;
}
declare const _default: CurriedUpdateIn;
export default _default;

12
types/util/curry.d.ts vendored Normal file
View File

@ -0,0 +1,12 @@
export declare const _ = "@@updeep/placeholder";
interface SprawlingCurry<R, A extends any[]> {
(...args: A): R;
(): SprawlingCurry<R, A>;
}
export declare function curry1<R, A>(fn: (a: A) => R): SprawlingCurry<R, [A]>;
export declare function curry1<R, A>(fn: (a: A, ...args: any) => R): SprawlingCurry<R, [A, ...any[]]>;
export declare function curry2(fn: any): any;
export declare function curry3(fn: any): any;
export declare function curry4(fn: any): any;
export default function curry(fn: (...args: any[]) => any, length?: 1 | 2 | 3 | 4): any;
export {};

2
types/util/splitPath.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
import { Path } from '../types';
export default function splitPath(path: Path): Array<string | number>;

8
types/withDefault.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
import { MergedUpdate } from './types';
export declare function withDefault<D, U, O>(defaultValue: D, updates: U, object: O): MergedUpdate<U, O extends null | undefined ? D : O>;
interface CurriedWithDefault {
<D, U, O extends any>(defaultValue: D, updates: U, object: O): MergedUpdate<U, O extends null | undefined ? D : O>;
<D, U>(defaultValue: D, updates: U): <O>(obj: O) => MergedUpdate<U, O extends null | undefined ? D : O>;
}
declare const _default: CurriedWithDefault;
export default _default;

2
types/wrap.d.ts vendored Normal file
View File

@ -0,0 +1,2 @@
import { ReturningFunction } from './types';
export default function wrap<F extends ReturningFunction, N extends number>(func: F, l?: N): any;