Skip to content
This repository has been archived by the owner on Feb 7, 2023. It is now read-only.

feat: add ModuleWorker type definitions #102

Closed
wants to merge 1 commit into from
Closed

Conversation

lukeed
Copy link
Contributor

@lukeed lukeed commented Aug 5, 2021

We're currently missing typedefs for creating module workers, so I included some that allow for strict-mode TS usage.

The ModuleWorker generic optionally accepts a typed Bindings interface, which will propagate to any fetch/scheduled handlers on the definition.

Included a strictly-typed module worker in the test.ts file, which makes use of the generic.

And then here's an example module worker, without any specific env typing, that is completely valid too:

// worker.ts
const worker: ModuleWorker = {
  fetch(req, env, ctx) {
    return new Response('OK');
  }
}

export default worker;

myKVNamespace.get("foo", {type: "stream"});

interface Env extends ModuleWorker.Bindings {
Copy link
Contributor Author

@lukeed lukeed Aug 5, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicitly defining all bindings that the worker (below) will have access to.
It extends the ModuleWorker.Bindings interface for strictness within the generic itself, but also to prevent a user from accidentally declaring an invalid value type – like FOO: number

}

const worker: ModuleWorker<Env> = {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define the ModuleWorker, passing thru the Env interface as the generic's type argument.

Doing this allows for strict type checks (and auto-complete) for all env parameter usage throughout the worker.

@lukeed
Copy link
Contributor Author

lukeed commented Aug 5, 2021

Not shown is the ability to define handler functions individually while still maintaining strict typing. This is because each handler definition is, itself, a generic:

// src/handlers.ts
export const fetcher: ModuleWorker.FetchHandler<Env> = async function (req, env, ctx) {
  // the `env` is strictly typed
  return new Response('OK');
}

// src/index.ts
import { fetcher } from './handlers';
export default { fetch: fetcher };

@GregBrimble
Copy link
Member

Fixes #76

Copy link
Member

@GregBrimble GregBrimble left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, lovely to get this in now. Thanks @lukeed! :)

@tylerbrostrom
Copy link

Hey this is great! What needs to happen to get this merged?

@mrbbot mrbbot mentioned this pull request Sep 24, 2021
threepointone added a commit that referenced this pull request Sep 30, 2021
Auto-Generated Types

Types are now automatically generated with releases by parsing the runtime's source code, and merging in overrides/docs defined in this repository (for generics, overloads, comments, etc).

webworker no longer needs to (and shouldn't) be included in tsconfig lib.

The final merged AST that's used to render the TypeScript types, workers.json, is also included in the repository. This could be used to generate bindings for other languages that compile to WebAssembly. Rust output is coming soon.

Closes: #55, #75, #76, #81, #84, #96, #97, #100, #101, #102, #105, #106, #107, #108
@mrbbot
Copy link
Contributor

mrbbot commented Sep 30, 2021

#112 has now been merged, which includes an ExportedHandler<Env> interface that behaves like ModuleWorker in this PR. It doesn't have the same restrictions on what bindings can look like though. Might want to update...

interface ExportedHandler<Env = unknown> {
...for that.

@maraisr
Copy link

maraisr commented Oct 19, 2021

When can we get this one merged?

@mrbbot
Copy link
Contributor

mrbbot commented Oct 19, 2021

@maraisr You can use the ExportedHandler<Env> interface in version 3.0.0 exactly like the ModuleWorker<Env> in this PR. 👍 We probably ought to close this PR, unless we want to add the same restrictions on what bindings can look like.

@lukeed
Copy link
Contributor Author

lukeed commented Oct 19, 2021

Yup it's the same, can alias it & bring the strict types too if you want

type Bindings = Record<string, KVNamespace | DurableObjectNamespace | string>;
type ModuleWorker<Env extends Bindings = Bindings> = ExportedHandler<Env>;

@lukeed lukeed closed this Oct 19, 2021
@lukeed lukeed deleted the feat/module-worker branch October 19, 2021 16:39
@maraisr
Copy link

maraisr commented Oct 19, 2021

Just a shame, the ergonomics about importing and defining a ModuleWorker just feels way more natural, than ExportsHandler. Not sure that'll be anybodys understanding of that type.

In any case, glad there's been efforts in this space!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants