graphql-nexus / nexus

Code-First, Type-Safe, GraphQL Schema Construction
https://nexusjs.org
MIT License
3.4k stars 275 forks source link

Promise error in Ghost example #30

Closed jakelowen closed 5 years ago

jakelowen commented 5 years ago

Using code copied straight from ghost example. UserSource byIdLoader throws a tslint error:

Code:

dataSources/UserLoader

import DataLoader from "dataloader";
import { byColumnLoader } from "../utils/loaderUtils";
import { Context } from "./Context";
import { dbt } from "../generated";

export class UserSource {
  constructor(protected ctx: Context) {}

  byIdLoader = new DataLoader<string, dbt.Users>(ids => {
    return byColumnLoader(this.ctx, "users", "id", ids);
  });

  byId(id: string) {
    return this.byIdLoader.load(id);
  }
}

utils/loaderUtils

import _ from "lodash";
import { DBTables } from "../generated/db-tables";
import { Context } from "../dataSources/Context";

export function byColumnLoader<
  Tbl extends keyof DBTables,
  Key extends Extract<keyof DBTables[Tbl], string>,
  KeyType extends Extract<DBTables[Tbl][Key], string | number>
>(
  ctx: Context,
  table: Tbl,
  key: Key,
  keys: KeyType[]
): PromiseLike<DBTables[Tbl][]> {
  return ctx
    .knex(table)
    .select(`${table}.*`)
    .whereIn(`${table}.${key}`, keys)
    .then((rows: DBTables[Tbl][]) => {
      const keyed: Record<KeyType, DBTables[Tbl]> = _.keyBy(rows, key);
      return keys.map(k => {
        return keyed[k] || new Error(`Missing row for ${table}:${key} ${k}`);
      });
    });
}

Gives tslint error:

Argument of type '(ids: string[]) => PromiseLike<Users[]>' is not assignable to parameter of type 'BatchLoadFn<string, Users>'.
  Type 'PromiseLike<Users[]>' is missing the following properties from type 'Promise<(Users | Error)[]>': catch, [Symbol.toStringTag], finallyts(2345)

image

tgriesser commented 5 years ago

I think you missed the dependencies. The example uses a fork of dataloader which includes this typings patch https://github.com/facebook/dataloader/pull/146 that was never merged. If you change byColumnLoader to be an async function (async byColumnLoader) it should work as well.