Comments (12)
I just hit this problem, where I tried to use hightlight.js
in a worker to generate some HTML that would be used in the browser. But that library explicitly references the DOM library types using /// <reference lib="dom" />
, which causes the same conflicts discussed here.
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 import {Response} from '@cloudflare/workers-types
.
from workers-types.
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 dom
and webworker
type package. So if you add workers-types
and dom
or webworker
you will get errors about conflicts.
What you can do today: The easiest thing you can do today is to remove the workers-types
package from your Remix (or other) codebase. If you'd still like type safety around Cloudflare specific APIs like KV, you can copy them directly from https://github.com/cloudflare/workers-types/blob/master/index.d.ts or build your own simplified version.
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 dom
and webworker
.
Does that sound right to you all?
from workers-types.
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?
from workers-types.
Hey! 👋 We're actively thinking about ways of fixing this in the next major version of workers-types
using the new type generation system. 👍
from workers-types.
Hey! 👋 As of @cloudflare/workers-types@4
, you can selectively import type { ... } from "@cloudflare/workers-types"
. Importantly, this plays nice with lib.dom
and lib.webworker
. https://github.com/cloudflare/workerd will be the home for types going forward, so we're archiving this repository now. If there's future discussions that needs to be had, we can open a new issue over there. 👍
from workers-types.
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 🤷♂️
from workers-types.
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 .server.ts
and .client.ts
and then they're typechecked separately. That moves it from the realm of core TS changes into supporting-tooling changes, which might be more realistic to implement.
from workers-types.
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 accept()
methods, etc), and behave more like @cloudflare/workers-types
version 2 and below. This could still be auto-generated (check if a type is also defined in lib.webworker
/lib.dom
, and ignore conflicting definitions in @cloudflare/workers-types
). This has the disadvantage of saying unimplemented APIs like MessageChannel
are valid in worker code. If we were really concerned about this, we could always write an ESLint rule for detecting if a browser API was used in worker code, although...
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>
);
}
from workers-types.
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 window
in a server rendered component 🙃 The ideas presented here seem like good ideas to me.
from workers-types.
I think
change the package from global types to types that need to be imported explicitly
sounds like a good idea!
from workers-types.
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 tsconfig.json
under compilerOptions.types
worked.
from workers-types.
Maybe we can make use of custom lib feature:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html
So we create an npm package that contains both lib dom and workers-type while removing dom types that are overrided by workers-types.
from workers-types.
Related Issues (20)
- Missing properties on IncomingRequestCfPropertiesBotManagement HOT 1
- Incorrect D1 types HOT 2
- RequestInit is missing some properties like 'cache' HOT 3
- Generate types from `workerd` RTTI HOT 1
- RFC: Exportable types HOT 7
- Fix `request.cf` types
- Generate exportable version of `workers-types` HOT 1
- add JSDocs documentation in types
- Move overrides to `workerd` C++ source code HOT 1
- Include C++ parameter names in types generated from JSG RTTI HOT 2
- Get type hints on incoming Request object HOT 4
- IncomingRequestCfPropertiesGeographicInformation makes geo property access an error (regression from 3.17.0) HOT 7
- HtmlRewriter ElementHandler methods can only accept strings (not general Content) HOT 1
- (3.18.0) IncomingRequestCfPropertiesGeographicInformation is the wrong type HOT 2
- Class 'Request<ParamKeyType, Data>' incorrectly extends base class 'Body' HOT 1
- `new Request` bad type HOT 8
- addEventListener has a broken type definition HOT 1
- NPM Release @cloudflare/worker-types 4.20221111.0 HOT 2
- Add Symbol.iterator to WebScoketPair HOT 1
- What is Fetcher for? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from workers-types.