Closed3

GraphQL Yoga で Resolver に渡す Context の dataSource の型に Interface を渡すと型エラーが出る

sasumasasasumasa

こういう Interface を定義していて

export interface IToDoListRepository {
  save(toDoList: ToDoList): Promise<PersistedToDoList | null>;
  findById(id: number): Promise<PersistedToDoList | null>;
}

こういう Context を定義していて

interface Context {
  dataSource: {
    todoListRepository: IToDoListRepository
  }
  admin: Admin
}

const resolvers: Resolvers<Context> = {

こういう Repository を実装し

そのクラスのインスタンスを Yoga に渡した場合

const yoga = createYoga({
  schema,
  context() {
    return {
      dataSource: {
        todoListRepository: new ToDoListRepository(),
      },
      admin: new Admin("sasumasa", new ID("Admin:1"))
    }
  }
})

こういうエラーが出る

sasumasasasumasa

エラーメッセージ的にみると dataSource の型として Interface を指定したが、実際に渡された ToDoListRepository はそれ以上のメソッドを持っているということで怒られているっぽい。

TS は構造的部分型なのでエラーが出ないと思っていたので「?」となっていた。
ちなみにこれはエラーがでないことを確認している。Context が特別なのか?

const testRepo: IToDoListRepository = new ToDoListRepository()
sasumasasasumasa

createContext 関数を定義し context に渡すだけで解決した

const createContext: () => Context = () => {
  return {
    dataSource: {
      todoListRepository: new ToDoListRepository(),
    },
    admin: new Admin("sasumasa", new ID("Admin:1"))
  };
}

const yoga = createYoga({
  schema,
  context: createContext
})

同じことをしているはずだが、先ほどのコードは context() の戻り値が createYoga() に渡される時にうまく型が推論されなかったのかもしれない。コードを分けて明示的に Context が返ってくれることを保証すること TS が推論せずとも型が一致することを保証できた、ということだろうか。

このスクラップは2023/10/28にクローズされました