-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Allow a union of libraries, for code that runs in multiple environments #52433
Comments
You can already have multiple tsconfig and change them in VSCode (or editor of your choice). Otherwise it sounds like a duplicate of #37884. |
Having to switch configs is a bad developer experience here. Although, if the editor performed the checking with multiple configs and presented a union of the errors, that might satisfy this feature request. Although, a single config that knows that the types are |
To take the example a bit further, imagine wanting to write this and tell developers it is safe to run in both workers and normal scripts:
This should compile. Right now, for this code to build you have to include the |
The problem we've had here in the past is that a huge amount of code can be seen to be running in one environment by inspection, but not in a way that's susceptible to static analysis. An example would be something like writing if ("document" in globalThis) {
window.addEventListener("click", () => {
localStorage.set("foo", "bar");
}
} This code is obviously fine, but TS would think that There's nothing today stopping someone from auto-genning variant DOM/webworker/etc libraries with every top-level declaration marked possibly- |
@RyanCavanaugh in those cases, I think it's reasonable to put a type guard on the global object, then access the APIs via the global object. Although, typescript could be smart and realise that if the type of |
As in: function globalIsWindow(global: any): global is Window {
return 'document' in global;
}
if (globalIsWindow(self)) {
self.addEventListener("click", () => {
self.localStorage.set("foo", "bar");
});
} But if TypeScript could determine that if (globalIsWindow(self)) {
- self.addEventListener("click", () => {
+ addEventListener("click", () => {
- self.localStorage.set("foo", "bar");
+ localStorage.set("foo", "bar");
});
} |
Perhaps this is what @jakearchibald is saying, but I noticed that predicates on If that could work, then it could be simplified to something like this: function isClient(): globalThis is Window {
return 'document' in globalThis;
} where global keywords can be used in predicates. |
Something like #50424 would make it a lot easier to create these kinds of isomorphic type guards, without needing to fork global type libs as @RyanCavanaugh suggests. |
Suggestion
π Search Terms
webworker, dom, node, isomorphic
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
Sometimes code is designed to run in multiple environments. For example, code may run in both nodejs and the browser, or a web page and a web worker.
Currently, you can use tsconfig to say your environment is both a 'DOM' and 'webworker', but that's never true in the wild. It's 'DOM' or 'webworker'.
Take this example (playground link):
TypeScript is fine with this if you include both 'DOM' and 'webworker' libs, but this code will fail in a webworker, because
localStorage
doesn't exist, and it will fail in a page, becauseimportScripts
doesn't exist.This would be solved by a feature that allows developers to specify the environment as A or B. The code above would show errors, because
localStoage
andimportScripts
may not exist.π Motivating Example
Hopefully the above description provides this.
π» Use Cases
Hopefully the above description provides this.
The text was updated successfully, but these errors were encountered: