Skip to content

Multiple projects with overlapping dependency graphs and different typings #21965

Closed
@OliverJAsh

Description

@OliverJAsh

I have an app with two TS (tsconfig.json) projects:

  • client: a browser app which uses the built-in typings from the dom lib
  • server: 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 and global.

However, this is not possible today, as the server/client TS projects would emit type errors on window or global access, respectively.

The only way this will work today is if both client and server 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:

  • referencing window from code that is only ever ran through Node (server), where window does not exist
  • referencing window from code that is ran on through both Node (server) and the browser (client), but without guarding for Node, where window does not exist

Ideally, TypeScript would allow shared files to reference typings in either TS project, but only after guarding first. For example:

// shared/Count.tsx

const getCount = () => {
  // `window` access is not available without guarding first
  if (typeof window !== 'undefined') {
    // `window` access is available here.
    return window.localStorage.getItem('count');
  } else {
    return undefined;
  }
};

// React component that is used on the client and server

const Count: SFC<{}> = () => {
  const count = getCount();

  if (count !== undefined) {
    return <div>Count is ${count}</div>;
  } else {
    return <div>Count unavailable</div>;
  }
};

Similarly, Node's global would only be available after guarding first.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions