-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
_annotation.ts
57 lines (50 loc) · 1.05 KB
/
_annotation.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
import type { Predicate } from "./type.ts";
// deno-lint-ignore no-explicit-any
export type Fn = (...args: any[]) => unknown;
export function annotate<F extends Fn, N extends string, V>(
fn: F,
name: N,
value: V,
): F & { [K in N]: V } {
return Object.defineProperties(fn, {
[name]: {
value,
},
}) as F & { [K in N]: V };
}
export function unannotate<F extends Fn, N extends string, V>(
fn: F & { [K in N]: V },
name: N,
): V {
return fn[name];
}
export function hasAnnotation<F extends Fn, N extends string>(
fn: F,
name: N,
): fn is F & { [K in N]: unknown } {
// deno-lint-ignore no-explicit-any
return !!(fn as any)[name];
}
/**
* Annotation for optional.
*/
export type AsOptional<T = unknown> = {
optional: Predicate<T>;
};
/**
* Annotation for readonly.
*/
export type AsReadonly<T = unknown> = {
readonly: Predicate<T>;
};
/**
* Annotation for predObj.
*/
export type IsPredObj<
T extends Record<PropertyKey, Predicate<unknown>> = Record<
PropertyKey,
Predicate<unknown>
>,
> = {
predObj: T;
};