-
Notifications
You must be signed in to change notification settings - Fork 29.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Node global interfaces redux #62782
Node global interfaces redux #62782
Changes from all commits
180d917
9428d92
916244f
436eaaf
79cfad4
06f03c5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -423,7 +423,7 @@ buff.writeDoubleBE(123.123, 0); | |
|
||
{ | ||
// $ExpectType Blob | undefined | ||
resolveObjectURL(URL.createObjectURL(new NodeBlob(['']))); | ||
resolveObjectURL(URL.createObjectURL(new Blob(['']))); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why did this one change? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a personal preference of mine, I don't like imports with names that shadow globals. (It can hide problems especially when the globals might be different as in this case.) If there's any problem with it you're more than welcome to change it back. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With I don't know if it should work, but the two types are incompatible, so I changed this test to show that. Once the types are not broken, we can figure out if the two Blob types should be compatible. |
||
} | ||
|
||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//// Test global event interfaces | ||
|
||
{ | ||
const e: Event = new Event(""); | ||
e.preventDefault(); | ||
// @ts-expect-error - ensure constructor does not return a constructor | ||
new e(); | ||
|
||
// Node's "DOM-like" Event differs from the real DOM in a few key aspects | ||
// $ExpectType boolean | ||
e.cancelBubble; | ||
e.composedPath(); | ||
// $ExpectType number | ||
e.eventPhase; | ||
|
||
const et: EventTarget = new EventTarget(); | ||
et.addEventListener("", () => {}, {passive: true}); | ||
// @ts-expect-error - ensure constructor does not return a constructor | ||
new et(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//// Test global event interfaces | ||
|
||
{ | ||
// Some event properties differ from DOM types | ||
const evt = new Event("fake"); | ||
evt.cancelBubble(); | ||
// @ts-expect-error | ||
evt.composedPath[2]; | ||
// $ExpectType 0 | 2 | ||
evt.eventPhase; | ||
|
||
// @ts-expect-error - ensure constructor does not return a constructor | ||
new evt(); | ||
|
||
const et: EventTarget = new EventTarget(); | ||
et.addEventListener("", () => {}, {passive: true}); | ||
// @ts-expect-error - ensure constructor does not return a constructor | ||
new et(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were these just missed in the original PR? Or are they new in 4.9’s lib.dom.d.ts?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can only answer the second part: AbortSignal is not new in 4.9, but it changed to add
timeout
(and once this is fixed, I'm going to addabort
in 4.9 as well in a few days).There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From discussion with @andrewbranch, it seems that @thw0rted answered the first question earlier in the typescript discord: it was indeed missed in the original PR, because it wasn't tested until now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sandersn Can you elaborate further on the source of this pattern please?
I am specifically interested in this pattern:
I am curious as to the origin of this pattern, which I traced to #34960 (comment) by @forivall.
Thanks 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got it from @thw0rted, where it was the first I had seen it. But it sounds like you've already done more detective work than I have.
I wish it wasn't necessary but it does help the types keep working even when certain globals are not defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't take credit -- if you look back at the original "remove DOM typings" PR, I link to a previous change to the Node typings that already used the same construct. I agree that it's not the great but unfortunately efforts to provide first-class language support for this kind of thing seem to have stalled out repeatedly over the years.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Conditional types are first-class support, for lots of kludgey things. =P
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thw0rted, I appreciate the clarity, but from my end, I am explicitly trying to look at the history of this to determine how stable it would be down the road for different use cases.
If there should be first-class support for this pattern or some other feature as a special case where module import order would augment the properties of
globalThis
, this needs more work on TypeScript's end, at least test cases to ensure the behaviour does not break.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's possible for import order to change the result, because the compiler would complain if the definitions created a circular reference, but I'm not confident in my analysis and would love to see smarter people than me really kick the tires with testing.
I also don't really want to see this pattern proliferate and take hold as a standard, because frankly it's pretty hard to reason about or even read and understand. I think there must be more elegant solutions to the problems we're trying to solve -- typings for idempotent libraries, and avoiding global scope pollution when frontend libraries and server-side tooling are installed at the same time -- but I don't personally have a cure-all to advocate for instead. This seemed like the least-worst compromise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thw0rted for reference, the earliest mention on a pull request was in #56163 (comment) from last year, but the earliest mention I found was #34960 (comment).
I agree with your points, and I think first TypeScript needs to settle on a way to define
globalThis
properties within modules and there needs to be mechanisms to model this behaviour at runtime when transpiling across module formats that would be deterministic.