GithubHelp home page GithubHelp logo

Comments (12)

petebacondarwin avatar petebacondarwin commented on July 16, 2024 5

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.

jkup avatar jkup commented on July 16, 2024 5

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.

geelen avatar geelen commented on July 16, 2024 1

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.

mrbbot avatar mrbbot commented on July 16, 2024 1

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.

mrbbot avatar mrbbot commented on July 16, 2024 1

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.

kentcdodds avatar kentcdodds commented on July 16, 2024

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.

geelen avatar geelen commented on July 16, 2024

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.

mrbbot avatar mrbbot commented on July 16, 2024

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.

kentcdodds avatar kentcdodds commented on July 16, 2024

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.

shwao avatar shwao commented on July 16, 2024

I think

change the package from global types to types that need to be imported explicitly

sounds like a good idea!

from workers-types.

isaac-mcfadyen avatar isaac-mcfadyen commented on July 16, 2024

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.

izznatsir avatar izznatsir commented on July 16, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.