Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Projection types not working in practice with zod or as parameters #318

Open
2 tasks done
zackdotcomputer opened this issue Jan 7, 2025 · 1 comment
Open
2 tasks done
Labels
bug Something isn't working

Comments

@zackdotcomputer
Copy link

zackdotcomputer commented Jan 7, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Code of Conduct

  • I agree to follow this project's Code of Conduct

Code Sandbox link

No response

Bug report

Running code as shown in the docs against my own schema is throwing a type error:

export type SchemaConfig = {
  schemaTypes: SanityTypes.AllSanitySchemaTypes;
  referenceSymbol: typeof SanityTypes.internalGroqTypeReferenceTo;
  parameters?: Record<string, unknown>;
};

const q = createGroqBuilder<SchemaConfig>();

q.star.filterByType("banner").project({
  title: q.string()
});

For reference, the Banner type inside of SanityTypes looks like:

export type Banner = {
  _id: string;
  _type: "banner";
  _createdAt: string;
  _updatedAt: string;
  _rev: string;
  title?: string;
}

That code has a build error at the .project call stating:

Argument of type '[]' is not assignable to parameter of type '["⛔️ Error: this projection has type mismatches: ⛔️"] | ["Error in \"title\": ⛔️ Parser expects a different input type ⛔️"]'.
  Type '[]' is not assignable to type '["Error in \"title\": ⛔️ Parser expects a different input type ⛔️"]'.
    Source has 0 element(s) but target requires 1.ts(2345)

If I replace the call with the shorthand form, then it compiles:

q.star.filterByType("banner").project({
  title: true
});

I think this is a result from the complexity of the ProjectionMap type being larger than the TS compiler can handle in practice. I've also been running into issues attempting to make a service function that takes in a GroqBuilder and projection, and would then call builder.filter(/* some common filters across my CMS */).project(projection) - it doesn't seem possible to define a parameter type for projection which will actually work as an argument to .project. Even directly copy-pasting it from the internal function declaration, I get type mismatch errors.

@zackdotcomputer zackdotcomputer added the bug Something isn't working label Jan 7, 2025
@nstam-stytch
Copy link

I believe I have the same issue, but let me know if I should file a different issue! I attempted to set up a simple query following the docs, which should just validate that a given slug exists:

const slugQuery = q
  .parameters<{ slug: string }>()
  .star.filterByType('page')
  .filterBy('slug.current == $slug')
  .slice(0)
  .project({
    route: q.slug('slug'),
  })
  .nullable();

In my exported Sanity types I have

export type Slug = {
  _type: 'slug';
  current?: string;
  source?: string;
};

export type Page = {
  { ... }
  slug?: Slug;
}

I get the type error Argument of type 'string' is not assignable to parameter of type 'never'. on the slug filter:
image

If I just use filter, so

const slugQuery = q
  .parameters<{ slug: string }>()
  .star.filter('_type === "page" && slug.current === $slug')
  .slice(0)
  .project({
    route: q.slug('slug'),
  })
  .nullable();

The typecheck passes, but the result of slugQuery is incorrect. InferResultType<typeof slugQuery> results in

type Slug = {
    route: never;
}[] | {
    route: never;
} | null

@nstam-stytch nstam-stytch mentioned this issue Jan 8, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants