keystone icon indicating copy to clipboard operation
keystone copied to clipboard

Low fidelity Typescript types for `context.query`

Open dmythro opened this issue 3 years ago • 11 comments
trafficstars

Steps to reproduce

Follow the docs link to create a project: How to embed Keystone + SQLite in a Next.js app.

Expected result

It builds just fine, dynamic lists typings are connected with imports.

Actual result

npm run build doesn't work:

image

List item types has any type (instead of Post for query.Post.findMany):

image

Node v14.18.1, macOS 12.1.

Workarounds

Currently I found out that it can be "fixed" by importing from .keystone/types and specifying types manually like this, for each usage on Next.js pages on frontend:

import { query } from '.keystone/api'
import { Lists } from '.keystone/types'

export async function getStaticProps() {
  const posts = (await query.Post.findMany({ query: 'id title slug' })) as Lists.Post.Item[]
  return { props: { posts } }
}

dmythro avatar Dec 20 '21 01:12 dmythro

Hi @dmythro, thanks for providing these details, we're aiming to get this tutorial fixed up in the next couple of days.

bladey avatar Dec 20 '21 05:12 bladey

Resolved in PR -- https://github.com/keystonejs/keystone/pull/7112

bladey avatar Dec 22 '21 03:12 bladey

Not a resolution I've been expecting for. Why query.Post.findMany(), for example, responds with any instead of Post.Item[] or something like that? Why there is no typing (and auto-complete) for query and possible lists etc?

The thing I mentioned is a workaround, not a solution. Manually overriding types is not really a good practice. So, I'd reopen this issue @bladey.

UPD:

  1. With latest release it works better with types, but still query.Post.findMany() is defined as Record<string, any>[] instead of Post[].
  2. Imported Lists is not actually used in Query Keystone from Next.js section.

dmythro avatar Dec 22 '21 10:12 dmythro

@bladey after this was released, I get error with keystone postinstall:

> keystone postinstall

Error: Cannot use GraphQLInputObjectType "IDFilter" from another module or realm.

Ensure that there is only one instance of "graphql" in the node_modules
directory. If different versions of "graphql" are the dependencies of other
relied on modules, use "resolutions" to ensure only one version is installed.

P.S. I've tried a clean install first, but only package-lock.json removal helped.

dmythro avatar Dec 22 '21 19:12 dmythro

Thanks @dmythro, I'll re-open this and re-evaulate with the team and get back to you with a response.

bladey avatar Dec 22 '21 23:12 bladey

Hey @dmythro , for the release errors, can you look at #7116 ? I identified what I think is the occurring problem there and how to solve it

Noviny avatar Dec 23 '21 01:12 Noviny

Hey @dmythro , for the release errors, can you look at #7116 ? I identified what I think is the occurring problem there and how to solve it

Thanks, as I wrote then and comments say, removing modules and a lock file solves the problem. Now sure why it happens anyways, maybe because related Keystone deps are not very strict across NPM modules?

dmythro avatar Dec 23 '21 16:12 dmythro

As shown in https://github.com/keystonejs/keystone/pull/7113/files, this problem is painful to resolve without duplicating your type definitions. Unfortunately the stringly-typed nature of the .query argument in await query.Post.findMany({ query: 'this is not well typed' }) needs to be parsed - or changed to something that can be easily parsed - for this to improve. This might need it's own GitHub issue, but, this will issue will do for now :+1: .

dcousens avatar Jan 04 '22 03:01 dcousens

@dcousens thanks! Yes, complete typings implementation looks complicated for this kind of queries, but at least I'd expect this to return something like a Partial<Post> (or to be more precise, Promise<Partial<Post>>).

dmythro avatar Jan 04 '22 10:01 dmythro

Unfortunately the GraphQL types are not exactly 1 to 1, so Partial<Post> might be OK, but not always depending on the field. This is an active point we are working on :+1:

dcousens avatar Jan 05 '22 05:01 dcousens

We've somewhat improved this with #7249 which is yet to be released and we're looking at improving this further

emmatown avatar Feb 10 '22 05:02 emmatown

Unfortunately the stringly-typed nature of the .query argument in await query.Post.findMany({ query: 'this is not well typed' }) needs to be parsed - or changed to something that can be easily parsed - for this to improve.

Delegating the parsing to codegen and using context.graphql.run instead of context.query seems to work for me -- I've just tried it now, this is by no mean backed by extensive testing or experience, but I wanted to share the idea.

rixo avatar Mar 12 '23 01:03 rixo

I am replacing this issue with the following technical discussion https://github.com/keystonejs/keystone/discussions/8498

dcousens avatar Apr 19 '23 23:04 dcousens