-
Notifications
You must be signed in to change notification settings - Fork 13
/
functions.ts
66 lines (58 loc) · 1.69 KB
/
functions.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* eslint-disable no-param-reassign */
import { toString } from './strings';
type ArgType<T> = T extends (...args: infer A) => any ? A : any;
/**
* Creates a function that is only invoked once
*/
export function once<T extends((...args: any[]) => any)>(fn: T): (
...args: ArgType<T>
) => ReturnType<T>|undefined {
let called = false;
return function _fn(...args: ArgType<T>): ReturnType<T>|undefined {
if (called) {
fn = undefined as any;
return undefined;
}
called = true;
return fn(...args);
};
}
/**
* A simple function that does nothing but return the first
* argument
*/
export function noop(...args: any[]): any {
return args[0];
}
function _getArgCacheKey(args: any[]): string {
const fixed = args.filter((a, i, arr) => {
if (a === undefined && arr.length === (i + 1)) return false;
return true;
});
try {
return JSON.stringify(fixed);
} catch (_e) {
return toString(fixed);
}
}
type MemoizeFn = (...args: any[]) => any;
/**
* A replacement for lodash memoize
*/
export function memoize<T extends MemoizeFn>(fn: T): T {
const _cache = new Map<string, any>();
const _memoize: any = (...args: any[]): any => {
const key = _getArgCacheKey(args);
const cached = _cache.get(key);
if (cached !== undefined) return cached;
const result = fn(...args);
_cache.set(key, result);
return result;
};
return _memoize;
}
/** Verify an input is a function */
// eslint-disable-next-line @typescript-eslint/ban-types
export function isFunction(input: unknown): input is Function {
return !!(input && typeof input === 'function');
}