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
Typegen not correctly typing groq query when using dynamic param on an object attribute #6365
Comments
I have the same issue, this could be very useful for field level translations ! |
Similar to this, the following query generates While if I use a string literal instead, the type is correctly generated as I also noticed while debugging this query that when using the parent accessor, the type results in In all these cases queries correctly work and bring the expected results. |
Hi! This is is a tricky feature because of the dynamic nature of GROQ. Given the look up |
One workaround I tried was to take my initial query with import groq from 'groq';
const fullWidthTextBlockFragment = `
_type == 'module.fullWidthTextBlock' => {
_key,
_type,
"title": title[$lang],
"body": body[$lang],
}
`;
const SanityProductModulesQuery = groq`
*[_type == 'product' && store.slug.current == $handle][0] {
modules[] {
${fullWidthTextBlockFragment},
}
}`;
const LocalizedProductModulesQuery = groq`
${SanityProductModulesQuery.replaceAll('[$lang]', '.en')}
`;
groq(`
*[_type == 'product' && store.slug.current == $handle][0] {
_type == 'module.fullWidthTextBlock' => {
"title": title[$lang],
"body": body[$lang],
}
}`,
{
lang: 'en',
},
);
|
It would be nice being able to at least define parameters in JSDoc (or similar) format for this feature work:
This approach might not be enough to unblock the usage of typed fragments though, which would be ideal. |
As a workaround, you could try to use export const testQuery = groq`
*[_type == "localizedDocument"][0] {
"body": select(
$locale == "en" => body.en,
$locale == "fr" => body.fr,
)
}
`; The resulting type of export type TestQueryResult = {
body: string | null;
} | null; However, this is inconvenient, because you always need to specify this selection. You could create a simple utility that reduces the burden of writing it. However, do not map over your export const selectLocalizedString = (field: string) =>
`select(
$locale == "en" => ${field}.en,
$locale == "fr" => ${field}.fr,
)`;
// ⚠ Does not work with TypeGen
// export const selectLocalizedString = (field: string) =>
// `select(
// ${supportedLanguages.map((lang) => `$locale == "${lang}" => ${field}.${lang},`).join("\n")}
// )`;
export const testQuery = groq`
*[_type == "localizedDocument"][0] {
"body": ${selectLocalizedString("body")}
}
`; Here's the full final file I used to reproduce your issue and find a working solution: import { groq } from "next-sanity";
import { defineField, defineType } from "sanity";
const supportedLanguages = ["en", "fr"] as const;
export const localizedString = defineType({
title: "Localized string",
name: "localizedString",
type: "object",
fields: supportedLanguages.map((lang) => ({
title: lang,
name: lang,
type: "string",
})),
});
export default defineType({
name: "localizedDocument",
title: "Localized Document",
type: "document",
fields: [
defineField({
name: "body",
title: "Body",
type: localizedString.name,
validation: (rule) => rule.required(),
}),
],
});
// export const testQuery = groq`
// *[_type == "localizedDocument"][0] {
// "body": select(
// $locale == "en" => body.en,
// $locale == "fr" => body.fr,
// )
// }
// `;
export const selectLocalizedString = (field: string) =>
`select(
$locale == "en" => ${field}.en,
$locale == "fr" => ${field}.fr,
)`;
// ⚠ Does not work with TypeGen
// export const selectLocalizedString = (field: string) =>
// `select(
// ${supportedLanguages.map((lang) => `$locale == "${lang}" => ${field}.${lang},`).join("\n")}
// )`;
export const testQuery = groq`
*[_type == "localizedDocument"][0] {
"body": ${selectLocalizedString("body")}
}
`; |
If you find a security vulnerability, do NOT open an issue. Email security@sanity.io instead.
Describe the bug
i have the following query:
*** This is working if i do directly access a locale: body.en
body is LocaleString which normally return
But i pass a locale to only get the currently selected lang in my website, so body is a string. But for some reason, typegen is still generatin this type:
To Reproduce
Steps to reproduce the behavior:
Expected behavior
I expect the typegen to generate the following type:
Which versions of Sanity are you using?
What operating system are you using?
Mac OS
Which versions of Node.js / npm are you running?
10.2.3
v18.19.0
The text was updated successfully, but these errors were encountered: