-
Notifications
You must be signed in to change notification settings - Fork 89
Using with a Workers SSR React app #164
Comments
Interesting problem! Feels like Remix is introducing new semantics for a single TS file, a bit like the way Vue did with its single-file components that had pretty dreadful editor support to start with, but came good due to its popularity & ergonomics. I wonder if you could end up with some kind of new TS syntax that supported this?: import { useLoaderData } from "remix";
import type { LoaderFunction } from "remix";
//// <implicit types="@cloudflare/workers-types" />
export let loader: LoaderFunction = () => {
return [{ name: "Pants" }, { name: "Jacket" }];
};
//// <implicit types="" lib="dom" />
export default function Products() {
let products = useLoaderData();
return (
<div>
<h1>Products</h1>
{products.map(product => (
<div>{product.name}</div>
))}
</div>
);
} Or something... nicer than that? But feels to me like you're wanting the TS compiler to understand that a single file is actually two different flavours of TS side-by-side and they'll get split apart before they get run? |
I think this has been a long-standing problem honestly. Ever since we started server rendering React we've had a file that could run in two different JS environments 🤷♂️ |
Yup, tbh I think this could even be an extension to this: microsoft/TypeScript#38511 Would be amazing to describe a module as requiring certain valid export types and that the body of each exported object be assumed to run in a particular environment. Might be a hard sell though... The other idea is that your file gets typechecked twice, basically split (based on some pragma) into a |
Hey! 👋 An extension to microsoft/TypeScript#38511 sounds awesome! In the short term though, since I imagine this would require some pretty fundamental changes to TypeScript, it might be sensible to export a version of these types that are strictly additive (i.e. with just KV namespace, Durable Object, WebSocket This gets really complicated if a function is used on both the client and server: import { useLoaderData } from "remix";
import type { LoaderFunction } from "remix";
export function helper() {
// Is this typed with @cloudflare/workers-types or dom, or some intersection of both?
// ...
return 42;
}
//// <implicit types="@cloudflare/workers-types" />
export let loader: LoaderFunction = () => {
return [{ name: "Pants", number: helper() }, { name: "Jacket" }];
};
//// <implicit types="" lib="dom" />
export default function Products() {
let products = useLoaderData();
return (
<div>
<h1>Products</h1>
{products.map(product => (
<div>{product.name}</div>
))}
<p>Important number: {helper()}</p>
</div>
);
} |
Yup, definitely looks like we're bumping up against the limits of TypeScript here 😅 I guess so far we've all just been fine with TypeScript not being able to catch when we're trying to access |
I just hit this problem, where I tried to use If workers-types cannot be made compatible with the DOM types, which I "think" would solve this, perhaps we should make the workers-types non-global? In other words, we would import them explicitly using something like |
Hey friends! I wanted to recap what's going on here with some actionable steps people can take today as well as what we should do in the future to resolve this! Let me know if I miss anything or get something wrong. The Problem: The issue here is that this package has global type definitions for a bunch of web APIs that conflict with the global type definitions for the same APIs provided by the What you can do today: The easiest thing you can do today is to remove the What we need to do soon: In lieu of TypeScript changing it's support in this matter, we should either export a version of this package with only Cloudflare specific types (like @mrbbot mentioned) or change the package from global types to types that need to be imported explicitly (like @petebacondarwin mentions). Either way we'll need to do some work to get this package to play nice with projects that are already using Does that sound right to you all? |
I think
sounds like a good idea! |
I'd just like to add on here for people looking at this in the future: I was actually getting errors because I didn't think to check if it was global or imported and just tried importing 🤦 Adding to |
Maybe we can make use of custom lib feature: So we create an npm package that contains both lib dom and workers-type while removing dom types that are overrided by workers-types. |
Hey! 👋 We're actively thinking about ways of fixing this in the next major version of |
Hey! 👋 As of |
Hey Cloudflare friends 👋
So I found a bit of a TypeScript problem with SSR React and Cloudflare. Based on workers-types, you shouldn't include the built-in DOM types on a Workers project which makes sense because workers isn't a DOM environment. The problem is that some of the code we're writing runs in the worker and some of it runs in the browser.
So I do need both types available in different parts of my file. Unfortunately AFAIK is not possible with TypeScript. So we need to have both types available for the whole file. Unfortunately, when I include DOM types with
@cloudflare/workers-types
, I get a bunch of errors because the types aren't compatible.I'm not sure what to do about this. Have y'all faced this before?
Here's what I get when I try to have both DOM and `@cloudflare/workers-types` at the same time:
The text was updated successfully, but these errors were encountered: