-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathderivable.ts
62 lines (56 loc) · 1.92 KB
/
derivable.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
// deno-lint-ignore-file no-explicit-any
type NonFunction<T> = T extends (...args: any[]) => any ? never : T;
/**
* A type that represents a value that can be either `T` or a function that returns `T`.
* Ensures `T` is not a function type.
*/
export type Derivable<T extends NonFunction<unknown>> = T | (() => T);
/**
* A map type where each property can either be of type `T` or a function that returns `T`.
*/
export type DerivableMap<M extends Record<string, NonFunction<unknown>>> = {
[K in keyof M]: Derivable<M[K]>;
};
/**
* An array type where each element can either be of type `T` or a function that returns `T`.
*/
export type DerivableArray<A extends readonly NonFunction<unknown>[]> = {
[K in keyof A]: Derivable<A[K]>;
};
/**
* Gets the value of a derivable, resolving it if it is a function.
*
* @param value - The derivable value or function.
* @returns The resolved value of type `T`.
*/
export function derive<T extends NonFunction<unknown>>(value: Derivable<T>): T {
return value instanceof Function ? value() : value;
}
/**
* Resolves all derivables in a map, returning the resolved values.
*
* @param map - An object where each property may be a derivable.
* @returns A new object with each property resolved.
*/
export function deriveMap<
M extends Record<PropertyKey, unknown>,
R extends { [K in keyof M]: M[K] extends Derivable<infer T> ? T : M[K] },
>(map: M): R {
return Object.fromEntries(
Object.entries(map).map(([k, v]) => {
return [k, derive(v)];
}),
) as R;
}
/**
* Resolves all derivables in an array, returning the resolved values.
*
* @param array - An array where each element may be a derivable.
* @returns A new array with each element resolved.
*/
export function deriveArray<
A extends readonly NonFunction<any>[],
R extends { [K in keyof A]: A[K] extends Derivable<infer T> ? T : A[K] },
>(array: A): R {
return array.map((v) => derive(v)) as unknown as R;
}