Redwood API - Alternative Types Definition Generator

Shipped 1.1.0 of the type generator, it now inlines the type narrowing for a resolver function’s return type making it trivial to re-use those in tests or through other files, with a focus on async funcs in particular:

For example:

import { db } from "src/lib/db";

export const gameSync = () => {}
export const gameAsync = async () => {}
export const gameAsync1Arg = (arg) => {}
export const gameAsync2Arg = (arg, obj) => {}
export const gameObj = {}

export const Game = {
  summary: "",
  summarySync: () => "",
  summaryAsync: async () => ""
};

Would get a d.ts like:

import type { Game as RTGame } from "./shared-return-types";
import type { Game as PGame } from "@prisma/client";
import type { GraphQLResolveInfo } from "graphql";
import type { RedwoodGraphQLContext } from "@redwoodjs/graphql-server/dist/functions/types";

/** SDL: gameSync: Game */
export interface GameSyncResolver {
  (args?: object, obj?: {...): RTGame | null | Promise<RTGame | null> | (() => Promise<RTGame | null>);
}

/** SDL: gameAsync: Game */
export interface GameAsyncResolver {
  (args?: object, obj?: { ... }): Promise<RTGame | null>;
}

/** SDL: gameAsync1Arg: Game */
export interface GameAsync1ArgResolver {
  (args: object, obj?: { ... }): RTGame | null | Promise<RTGame | null> | (() => Promise<RTGame | null>);
}

/** SDL: gameAsync2Arg: Game */
export interface GameAsync2ArgResolver {
  (args: object, obj: { ... }): RTGame | null | Promise<RTGame | null> | (() => Promise<RTGame | null>);
}

/** SDL: gameObj: Game */
export interface GameObjResolver {
  (args?: object, obj?: { ... }): RTGame | null;
}

type GameAsParent<Extended> = PGame & {
  summary: () => Promise<string>,
  summarySync: () => Promise<string>,
  summaryAsync: () => Promise<string>
} & Extended;

export interface GameTypeResolvers<Extended> {

  /** SDL: summary: String! */
  summary: string;

  /** SDL: summarySync: String! */
  summarySync: (args?: undefined, obj?: { ... }) => string | Promise<string> | (() => Promise<string>);

  /** SDL: summaryAsync: String! */
  summaryAsync: (args?: undefined, obj?: { ... }) => Promise<string>;
}

In concrete terms, for something like summaryAsync or gameAsync which are the majority of my resolvers (and nearly always the ones I want to test) the type has gone from string | Promise<string> | (() => Promise<string>); to Promise<string> - which means your tests dont need an as to tell TS you know the types.

In theory, I could do the same for a non async function, but it’d need to use the types from TypeScript, and I’m not gonna slow down the generator for that as I want it on an instant watch-mode eventually.

2 Likes