Commit a356bc3
## Motivation
The `ControllerMessenger` pattern that is used in all of our controllers
currently relies on unsafe typing, which includes `any` usage. A more
rigorous overhaul of these definitions will help us implement features
with more type-safe and robust code.
## Explanation
### Main
- Removes all `any` usage from `Action`, `Event` typing in
`ControllerMessenger`.
- Types `Action['handler']` with correct universal supertype for
functions.
- Fixes `SelectorFunction`, `EventSubscriptionMap` typing that was
causing errors.
- Improves `BaseController` typing by defining `NamespacedName` type:
the narrowest supertype of all names defined within a given namespace.
- `BaseController` now expects a "getState" action type and
"stateChange" event type in all controllers.
### Auxiliary
- Improved typing for `deriveStateFromMetadata`
- ~Rename all single-letter type param names to be more descriptive.~
(moved here: #2030)
### Notes on the "universal function supertype"
#### A. `(...args: never[]) => unknown`
`Action['handler'] extends ActionConstraint['handler']`, and in general
`Subtype extends Supertype`. Therefore, in order to assign any function
to `Action['handler']` without restrictions, we need
`ActionConstraint['handler']` to be the widest possible function i.e.
the supertype of all functions.
To achieve this, the return type of this supertype function needs to be
`unknown` (universal supertype), and the parameters need to be `never`
(universal subtype). This is because in general `(x: SuperType) => T` is
a *subtype* of `(x: SubType) => T`. So the params need to be the
narrowest type (i.e. `never`) for the function type to be widened into
the universal function supertype.
- There's an example of this in the [TypeScript
docs](https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types).
- And here's a more detailed [reddit
comment](https://www.reddit.com/r/typescript/comments/muyl55/comment/gv9ndij/?utm_source=share&utm_medium=web2x&context=3)
on this topic.
#### B. `(...args: never) => unknown`
In general, array types of arbitrary length are not assignable to tuple
types that have fixed types designated to some or all of its index
positions (the array is wider than the tuple since it has less
constraints).
This means that there's a whole subcategory of functions that `(...args:
never[]) => unknown` doesn't cover: functions that have a finite number
of parameters that are strictly ordered and typed, making their spread
argument list evaluate as a fixed-length or variadic **tuple** type,
instead of a freely expandable (or contractable) **array** type.
That is, `(...args: never[]) => unknown` covers the cases where all of
the params can be typed together as a group e.g. `(...args: (string |
number)[]) => T`. But to cover cases like `(a: string, b: number,
...rest: unknown[]) => T`, we need another top type with an even
narrower type for the params: `(...args: never) => unknown`.
#### C. `((...args: never) => unknown) | ((...args: never[]) =>
unknown)`
In short, the above represents the top type that includes both of these
function categories.
- `| never` in general is analogous to `+ 0`, so `(...args: (never[] |
never)) => unknown` doesn't work.
- `(...args: never) => unknown` doesn't work with the error message
`Type 'T[]' is not assignable to type 'never'`.
## References
- Closes #2026
## Changelog
### `@metamask/base-controller`
- **CHANGED**: `ActionConstraint['handler']` has been fixed to remove
`any` usage, and is now defined as the universal supertype of all
functions, meaning any function can be safely assigned to it, regardless
of argument types, number of arguments, or return value type.
- **CHANGED** : `ExtractActionParameters` and `ExtractActionResponse`
have also been fixed to remove `any` usage, and to use the new typing of
`ActionConstraint['handler']`.
- **CHANGED**: **BREAKING** Alters `SelectorFunction` type, replacing
its `Args` generic parameter with an event payload type that is defined
with a new required generic parameter `Event`.
- **ADDED**: Exports `NamespacedName` type, which is the narrowest
supertype of all names defined within a given namespace.
### `@metamask/rate-limit-controller`
- **CHANGED**: **BREAKING** `RateLimitedApi['method']` is now
constrained by the `ActionConstraint['handler']` type from the
`@metamask/base-controller` module.
## Checklist
- [x] I've updated the test suite for new or updated code as appropriate
- [x] I've updated documentation (JSDoc, Markdown, etc.) for new or
updated code as appropriate
- [x] I've highlighted breaking changes using the "BREAKING" category
above as appropriate
---------
Co-authored-by: Mark Stacey <[email protected]>
Co-authored-by: Elliot Winkler <[email protected]>
1 parent 07224cf commit a356bc3
File tree
3 files changed
+114
-47
lines changed- packages
- base-controller/src
- rate-limit-controller/src
3 files changed
+114
-47
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
| 7 | + | |
6 | 8 | | |
7 | | - | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
62 | 63 | | |
63 | 64 | | |
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 | + | |
65 | 92 | | |
66 | 93 | | |
67 | 94 | | |
68 | 95 | | |
69 | 96 | | |
70 | 97 | | |
71 | | - | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
72 | 105 | | |
73 | 106 | | |
74 | 107 | | |
| |||
164 | 197 | | |
165 | 198 | | |
166 | 199 | | |
167 | | - | |
| 200 | + | |
168 | 201 | | |
169 | 202 | | |
170 | 203 | | |
| |||
183 | 216 | | |
184 | 217 | | |
185 | 218 | | |
186 | | - | |
| 219 | + | |
187 | 220 | | |
188 | 221 | | |
189 | 222 | | |
| |||
199 | 232 | | |
200 | 233 | | |
201 | 234 | | |
202 | | - | |
203 | | - | |
204 | | - | |
| 235 | + | |
205 | 236 | | |
206 | 237 | | |
207 | 238 | | |
| |||
250 | 281 | | |
251 | 282 | | |
252 | 283 | | |
253 | | - | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
254 | 287 | | |
255 | | - | |
| 288 | + | |
256 | 289 | | |
257 | | - | |
| 290 | + | |
258 | 291 | | |
259 | 292 | | |
260 | 293 | | |
261 | 294 | | |
262 | | - | |
263 | | - | |
264 | | - | |
| 295 | + | |
265 | 296 | | |
266 | | - | |
| 297 | + | |
267 | 298 | | |
268 | 299 | | |
269 | 300 | | |
| |||
274 | 305 | | |
275 | 306 | | |
276 | 307 | | |
277 | | - | |
| 308 | + | |
278 | 309 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
2 | 5 | | |
3 | 6 | | |
4 | | - | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
5 | 12 | | |
6 | | - | |
| 13 | + | |
7 | 14 | | |
8 | 15 | | |
9 | 16 | | |
10 | | - | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
11 | 22 | | |
12 | | - | |
| 23 | + | |
13 | 24 | | |
14 | 25 | | |
15 | 26 | | |
16 | 27 | | |
17 | | - | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
18 | 32 | | |
19 | 33 | | |
20 | 34 | | |
21 | 35 | | |
22 | 36 | | |
23 | 37 | | |
24 | 38 | | |
25 | | - | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
26 | 44 | | |
27 | 45 | | |
28 | 46 | | |
29 | | - | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
30 | 50 | | |
31 | 51 | | |
32 | 52 | | |
33 | 53 | | |
34 | | - | |
35 | | - | |
| 54 | + | |
| 55 | + | |
36 | 56 | | |
37 | 57 | | |
38 | 58 | | |
| |||
41 | 61 | | |
42 | 62 | | |
43 | 63 | | |
44 | | - | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
45 | 69 | | |
46 | | - | |
47 | 70 | | |
48 | | - | |
49 | | - | |
50 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
51 | 77 | | |
52 | 78 | | |
53 | 79 | | |
| |||
62 | 88 | | |
63 | 89 | | |
64 | 90 | | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
65 | 94 | | |
66 | 95 | | |
67 | 96 | | |
| |||
151 | 180 | | |
152 | 181 | | |
153 | 182 | | |
154 | | - | |
| 183 | + | |
155 | 184 | | |
156 | 185 | | |
157 | | - | |
| 186 | + | |
158 | 187 | | |
159 | 188 | | |
160 | 189 | | |
| |||
177 | 206 | | |
178 | 207 | | |
179 | 208 | | |
180 | | - | |
| 209 | + | |
181 | 210 | | |
182 | 211 | | |
183 | 212 | | |
| |||
202 | 231 | | |
203 | 232 | | |
204 | 233 | | |
205 | | - | |
| 234 | + | |
206 | 235 | | |
207 | 236 | | |
208 | 237 | | |
| |||
227 | 256 | | |
228 | 257 | | |
229 | 258 | | |
230 | | - | |
| 259 | + | |
231 | 260 | | |
232 | 261 | | |
233 | 262 | | |
| |||
252 | 281 | | |
253 | 282 | | |
254 | 283 | | |
255 | | - | |
| 284 | + | |
256 | 285 | | |
257 | 286 | | |
258 | 287 | | |
| |||
276 | 305 | | |
277 | 306 | | |
278 | 307 | | |
279 | | - | |
| 308 | + | |
280 | 309 | | |
281 | 310 | | |
282 | 311 | | |
283 | 312 | | |
284 | 313 | | |
285 | | - | |
| 314 | + | |
286 | 315 | | |
287 | 316 | | |
288 | 317 | | |
| |||
312 | 341 | | |
313 | 342 | | |
314 | 343 | | |
315 | | - | |
| 344 | + | |
316 | 345 | | |
317 | 346 | | |
318 | 347 | | |
| |||
335 | 364 | | |
336 | 365 | | |
337 | 366 | | |
338 | | - | |
| 367 | + | |
339 | 368 | | |
340 | 369 | | |
341 | 370 | | |
| |||
362 | 391 | | |
363 | 392 | | |
364 | 393 | | |
365 | | - | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
366 | 398 | | |
367 | 399 | | |
368 | 400 | | |
| |||
Lines changed: 10 additions & 6 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
2 | 5 | | |
3 | 6 | | |
4 | 7 | | |
| |||
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
13 | | - | |
| 16 | + | |
14 | 17 | | |
15 | 18 | | |
16 | 19 | | |
| |||
121 | 124 | | |
122 | 125 | | |
123 | 126 | | |
124 | | - | |
| 127 | + | |
125 | 128 | | |
126 | 129 | | |
127 | 130 | | |
128 | | - | |
| 131 | + | |
129 | 132 | | |
130 | 133 | | |
131 | 134 | | |
| |||
135 | 138 | | |
136 | 139 | | |
137 | 140 | | |
138 | | - | |
139 | 141 | | |
140 | 142 | | |
141 | 143 | | |
| |||
155 | 157 | | |
156 | 158 | | |
157 | 159 | | |
158 | | - | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
159 | 163 | | |
160 | 164 | | |
161 | 165 | | |
| |||
0 commit comments