inngest / inngest-js

The developer platform for easily building reliable workflows with zero infrastructure for TypeScript & JavaScript
https://www.inngest.com/
GNU General Public License v3.0
414 stars 41 forks source link

Relax middleware reqArgs type from unknown to any #558

Closed arjunyel closed 3 months ago

arjunyel commented 5 months ago

Summary

When I am trying to type my Inngest Hono middleware

import type { Context, Env } from "hono";
import type { BlankInput } from "hono/types";
import { InngestMiddleware } from "inngest";

export const honoMiddleware = new InngestMiddleware({
  name: "Hono Middleware",
  init() {
    return {
      onFunctionRun({
        reqArgs: [c],
      }: {
        reqArgs: Readonly<
          Context<
            Env,
            "/api/inngest",
            BlankInput
          >[]
        >;
      }) {
        return {
          transformInput() {
            return {
              ctx: {
                c,
              },
            };
          },
        };
      },
    };
  },
});

I currently get the error

Type '() => { onFunctionRun({ reqArgs, }: { reqArgs: readonly Context<Env, "/api/inngest", BlankInput>[]; }): { transformInput(): { ctx: { c: Context<Env, "/api/inngest", BlankInput>; }; }; }; }' is not assignable to type 'MiddlewareRegisterFn'.
  Type '{ onFunctionRun({ reqArgs, }: { reqArgs: readonly Context<Env, "/api/inngest", BlankInput>[]; }): { transformInput(): { ctx: { c: Context<Env, "/api/inngest", BlankInput>; }; }; }; }' is not assignable to type 'MaybePromise<MiddlewareRegisterReturn>'.
    Type '{ onFunctionRun({ reqArgs, }: { reqArgs: readonly Context<Env, "/api/inngest", BlankInput>[]; }): { transformInput(): { ctx: { c: Context<Env, "/api/inngest", BlankInput>; }; }; }; }' is not assignable to type 'MiddlewareRegisterReturn'.
      Types of property 'onFunctionRun' are incompatible.
        Type '({ reqArgs, }: { reqArgs: readonly Context<Env, "/api/inngest", BlankInput>[]; }) => { transformInput(): { ctx: { c: Context<Env, "/api/inngest", BlankInput>; }; }; }' is not assignable to type '(ctx: Readonly<{ readonly steps: Readonly<{ id: string; data?: any; error?: any; }>[]; readonly fn: Any; readonly reqArgs: readonly unknown[]; ctx: Pick<Record<string, unknown> & Readonly<BaseContext<Any, string>>, "event" | "runId">; }>) => MaybePromise<...>'.
          Types of parameters '__0' and 'ctx' are incompatible.
            Type 'Readonly<{ readonly steps: Readonly<{ id: string; data?: any; error?: any; }>[]; readonly fn: Any; readonly reqArgs: readonly unknown[]; ctx: Pick<Record<string, unknown> & Readonly<BaseContext<Any, string>>, "event" | "runId">; }>' is not assignable to type '{ reqArgs: readonly Context<Env, "/api/inngest", BlankInput>[]; }'.
              Types of property 'reqArgs' are incompatible.
                Type 'readonly unknown[]' is not assignable to type 'readonly Context<Env, "/api/inngest", BlankInput>[]'.
                  Type 'unknown' is not assignable to type 'Context<Env, "/api/inngest", BlankInput>'.

Checklist

Related

Also fixed lint errors that popped up

changeset-bot[bot] commented 5 months ago

🦋 Changeset detected

Latest commit: 6cfed312be774791ff4ff19c572fc8275274afe8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package | Name | Type | | ------- | ----- | | inngest | Minor |

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

jpwilliams commented 3 months ago

Thanks for the PR, @arjunyel!

The idea of reqArgs being unknown is that middleware should make sure that it asserts at runtime the type of the arguments being passed in. While this middleware is hand-rolled just for Hono, they're intended to be portable and something that will function across many serve handlers; using unknown ensures developers account for that when writing.

For your example above, you could change the assertion to be within the function and the error should disappear:

import type { Context, Env } from "hono";
import type { BlankInput } from "hono/types";
import { InngestMiddleware } from "inngest";

export const honoMiddleware = new InngestMiddleware({
  name: "Hono Middleware",
  init() {
    return {
      onFunctionRun({ reqArgs }) {
        const [c] = reqArgs as [
          Readonly<Context<Env, "/api/inngest", BlankInput>>,
        ];

        return {
          transformInput() {
            return {
              ctx: {
                c,
              },
            };
          },
        };
      },
    };
  },
});

Ideally, you could change this to an actual runtime assertion to ensure there are no surprises, though the complexity of that depends on the shape of a Context instance and whether or not it's exported by hono.

Closing this as it's working as intended.