Breaks with @types/node@18.8.5, Type '...' is not assignable to type 'Event'. ts2322
Vue version
(Not related)
Link to minimal reproduction
Steps to reproduce
Make sure to have vue
and @types/node
installed.
const T = <div onClick={() => {}} />
What is expected?
No type error
What is actually happening?
Type '() => void' is not assignable to type 'MouseEvent'. (2322)
System Info
(Unrelated)
Any additional comments?
This is caused by https://github.com/DefinitelyTyped/DefinitelyTyped/pull/59905.
Vue uses the following code to get generate the signature of event handlers:
And Vue maintains an event map. It tests each property is assignable to Function (interface).
On the other side, @types/node introduces a new change to include browser types that are implemented in Node, which is, unfortunately, incompatible with DOM.
The PR is intended to not re-declaring the existing type (from libdom) if possible (which is not possible in TypeScript), but they're doing it in the wrong way.
It augmented the global Event interface with __Event
declare global {
interface Event extends __Event {}
// ...
}
And __Event
is defined in the following way:
type __Event = typeof globalThis extends { onmessage: any, Event: infer T }
// ~~~~~~~ wrong
? T
: // Node's definition ...
It tries to reuse the global Event
value (which is NOT the global interface Event
), which means __Event
is the constructor of DOM Events.
Because (AFAIK) it is impossible to "reflect" a type out to solve this problem.
// Note: globalThis is a namespace
namespace Test {
export interface Name { value: 1 }
export var Name: Function & { value: 2 }
}
type _ = [
Test.Name['value'], // 1
typeof Test.Name['value'], // 2
typeof Test extends { Name: infer N } ? N : never
// Function & { value: 2 }
]
This brings us back to the Vue side.
With the augmented global Event
interface, now all DOM events (MouseEvent
, KeyboardEvent
, etc) are now inherited from the global Event constructor (from the value namespace).
type EventHandlers<E> = {
[K in keyof E]?: E[K] extends Function ? E[K] : (payload: E[K]) => void
}
And E[K]
(Events) now all passes the extends Function
test and makes all DOM JSX types broken (they're now typed as onClick?: MouseEvent | undefined
).
Also opened an issue in DT repo https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/62759
Comment by sodatea in the PR: 15 hours ago
FYI the issue has been fixed in @types/node v18.11.1+ so you don't have to wait for this PR to be merged to update your @types/node version.