You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The ObservableV2 class allows the specification of a type which defines the set of events and callbacks, but the template is overly permissive. Namely, the EVENT parameter can constrain the callbacks such that every callback must return a value. This possibility makes it very difficult to write well-typed abstractions over ObservableV2 (they must handle the case where EVENTS has been instantiated this way).
Argument of type '() => void' is not assignable to parameter of type '() => number'.
Type 'void' is not assignable to type 'number'.ts(2345)
Expected behavior ObservableV2 should always allow callbacks that return void.
Additional context
I ran into this problem while trying to write a utility function called waitUntil that runs a test on all emitted events and resolves a promise when it successfully passes the test. The untyped form is basically:
Unfortunately it's impossible (or at least beyond me) to make the function cb inside waitUntil typecheck because the observable could require that callbacks for this event return a value.
The text was updated successfully, but these errors were encountered:
We can remove the degree of freedom from the type by simply not allowing the EVENT variable to define return types. Instead, using a map from event name to a list of parameter types.
- * @template {{[key in keyof EVENTS]: function(...any):void}} EVENTS+ * @template {{[key in keyof EVENTS]: any[]}} EVENTS
*/
export class ObservableV2 {
and then on the methods:
- * @param {EVENTS[NAME]} f+ * @param {(...args: EVENTS[NAME]) => void} f
*/
on (name, f) {
As shown above, the return type information in the EVENTS map should be ignored. The solution above removes them so there's no more extraneous information in the type, but we could just ignore the return type by changing the types on the methods:
- * @param {EVENTS[NAME]} f+ * @param {(...args: Parameters<EVENTS[NAME]>) => void} f
*/
on (name, f) {
Describe the bug
The
ObservableV2
class allows the specification of a type which defines the set of events and callbacks, but the template is overly permissive. Namely, theEVENT
parameter can constrain the callbacks such that every callback must return a value. This possibility makes it very difficult to write well-typed abstractions overObservableV2
(they must handle the case whereEVENTS
has been instantiated this way).To Reproduce
Here's a small example of this in typescript:
Which results in the error:
Expected behavior
ObservableV2
should always allow callbacks that returnvoid
.Additional context
I ran into this problem while trying to write a utility function called
waitUntil
that runs a test on all emitted events and resolves a promise when it successfully passes the test. The untyped form is basically:This lets me write nice little functions like:
Unfortunately it's impossible (or at least beyond me) to make the function
cb
insidewaitUntil
typecheck because the observable could require that callbacks for this event return a value.The text was updated successfully, but these errors were encountered: