This repository has been archived by the owner on Sep 16, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
aspect.ts
145 lines (135 loc) · 4.77 KB
/
aspect.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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import { InControl } from './control';
/**
* Some aspect of the user input. Such as input focus or validity.
*
* An aspect is applied to input control first. This creates an aspect instance bound to that control. All
* aspect-related operations are performed by that instance.
*
* @category Aspect
* @typeParam TInstance - Aspect instance type.
* @typeParam TKind - Aspect application kind.
*/
export interface InAspect<TInstance, TKind extends InAspect.Application.Kind = 'default'> {
/**
* Applies this aspect to the given input `control`.
*
* This method is called at most once per control when requested aspect is not applied to the control yet.
*
* @typeParam TValue - Input value type.
* @param control - Input control to apply aspect to.
*
* @returns An aspect applied to the given `control`.
*/
applyTo<TValue>(control: InControl<TValue>): InAspect.Applied<TValue, TInstance>;
}
/**
* A symbol of aspect key property containing a reference to aspect.
*
* @category Aspect
*/
export const InAspect__symbol = /*#__PURE__*/ Symbol('in-aspect');
/**
* @category Aspect
*/
export namespace InAspect {
/**
* A key of the aspect of user input.
*
* It is passed to `InControl.aspect()` method in order to apply target aspect to that control.
*
* This interface is typically implemented by aspect instance class object. I.e. by its static methods.
*
* @typeParam TInstance - Aspect instance type.
* @typeParam TKind - Aspect application kind.
*/
export interface Key<TInstance, TKind extends Application.Kind = 'default'> {
/**
* A referenced aspect of user input.
*/
[InAspect__symbol]: InAspect<TInstance, TKind>;
}
/**
* An input aspect applied to control.
*
* This is what returned from `InAspect.applyTo()` method. Contains aspect instance and its manipulation methods.
*
* @typeParam TValue - Input value type.
* @typeParam TInstance - Aspect instance type.
* @typeParam TConvertedInstance - A type of aspect instance applied to converted control.
* The same as `Instance` by default.
*/
export interface Applied<TValue, TInstance, TConvertedInstance extends TInstance = TInstance> {
/**
* Input aspect instance.
*/
readonly instance: TInstance;
/**
* Converts an aspect to another value type.
*
* This method is called by input control created by {@link InControl.convert} method.
*
* @typeParam TTargetValue - Converted input value type.
* @param target - Target input control.
*
* @returns The same aspect applied to `target` control, or `undefined` if aspect can not be converted.
*/
convertTo<TTargetValue>(
target: InControl<TTargetValue>,
): Applied<TTargetValue, TConvertedInstance> | undefined;
/**
* Converts an aspect to the same value type.
*
* When defined, this method is called instead of {@link convertTo} when converting aspect for converted control
* with the same value. I.e. when {@link InConverter.Aspect aspect-only converters} used for conversion.
*
* @param target - Target input control.
*
* @returns The same aspect applied to `target` control, or `undefined` if aspect can not be converted.
*/
attachTo?(target: InControl<TValue>): Applied<TValue, TInstance> | undefined;
}
export namespace Application {
/**
* A kind of input aspect application.
*
* This is a key of `InAspect.Application.Map` type.
*/
export type Kind = keyof Map<unknown, unknown>;
/**
* A type of input aspect application result of the given application kind and input value type.
*
* @typeParam TInstance - Aspect instance type.
* @typeParam TValue - Input value type.
* @typeParam TKind - Aspect application kind.
*/
export type Result<TInstance, TValue, TKind extends Kind> = Applied<
TValue,
Instance<TInstance, TValue, TKind>
>;
/**
* A type of applied aspect instance of the given application kind and input value type.
*
* @typeParam TInstance - Aspect instance type.
* @typeParam TValue - Input value type.
* @typeParam TKind - Aspect application kind.
*/
export type Instance<TInstance, TValue, TKind extends Kind> = ReturnType<
Map<TInstance, TValue>[TKind]
>;
/**
* A map implementing application result detection algorithms.
*
* Each method name here is a kind of aspect application, while the return value of this method is an aspect
* instance type.
*
* @typeParam TInstance - Aspect instance type.
* @typeParam TValue - Input value type.
*/
export interface Map<TInstance, TValue> {
/**
* Default aspect application type. Just an aspect instance type.
*/
default(): TInstance;
}
}
}