-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Multiple projects with overlapping dependency graphs and different typings #21965
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
Comments
I wonder if something like #14052 would help? I think this would be a great practical use case to add to the discussion there. More flexibility with manipulating the global environment through types would be great. |
@OliverJAsh it wouldn't solve this issue as it is currently proposed, but I think a better approach to globals could solve both that and this issue, and others like #10050. Actually, could you do something like this now? // In your server project only:
// node.d.ts is present in this build, so `Global` and `global` will be fully defined
interface Window {[x: string]: any; }
declare let window: Window | undefined;
// In your client project only:
// dom.d.ts is present in this build, so `Window` and `window` will be fully defined
interface Global {[x: string]: any; }
declare let global: Global | undefined;
// In your shared code (compiled into both client and server builds):
window.x; // ERROR: Object is possibly 'undefined'
if (typeof window !== 'undefined') {
window.x; // OK
}
global.x; // ERROR: Object is possibly 'undefined'
if (typeof global !== 'undefined') {
global.x; // OK
} Provided all your global accesses go through properties on |
@yortus Good idea, and one that @samijaber also raised offline. I think that would get us some of the way, however Declaring them as window; // ERROR: Window does not exist in all environments
if (typeof window !== 'undefined') { // Safe to use the reference with `typeof`
window.x; // OK
} |
Yes right. That would indeed be something new in TypeScript. Even optional properties can be referenced, so optional globals wouldn't help. You basically want to be able to blacklist an identifier, like having a 'negative' declaration. |
The lib file, be it |
That would still allow |
Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed. |
@mhegazy Did you have any thoughts in response to my last comment? I would like to re-open this issue, as the suggested workaround does not help. |
I have an app with two TS (
tsconfig.json
) projects:client
: a browser app which uses the built-in typings from thedom
libserver
: a Node app which uses the types package@types/node
The dependency graph of these projects overlap slightly, as we have components that are server and client rendered. We will refer to files in this overlap as "shared".
I want to be able to access both client-only and server-only constructors in shared files, e.g.
window
andglobal
.However, this is not possible today, as the server/client TS projects would emit type errors on
window
orglobal
access, respectively.The only way this will work today is if both
client
andserver
TS projects specify typings for Node and the browser. However, this is problematic because the typings do not correspond with the environment the code will run in, and mistakes are easily made, such as:window
from code that is only ever ran through Node (server
), wherewindow
does not existwindow
from code that is ran on through both Node (server
) and the browser (client
), but without guarding for Node, wherewindow
does not existIdeally, TypeScript would allow shared files to reference typings in either TS project, but only after guarding first. For example:
Similarly, Node's
global
would only be available after guarding first.The text was updated successfully, but these errors were encountered: