TypeScript code generation and StructuredText value types

Hey :wave:,
I was reading through the blog post How To Generate TypeScript Types From GraphQL and encountered the following problem when I have a query retrieving a Structured text field.

The “value” parameter has the type “unknown” in the generated type which causes an TypeScript error on the data prop when using the <StructuredText /> component:

Type ‘unknown’ is not assignable to type ‘Document | Node | StructuredText<Record, Record> | null | undefined’.ts(2322)

Here is my query:

query FrontPage($id: ItemId) {
  landingFrontPage(filter: { id: { eq: $id } }) {
    name
    structuredContent {
      value
    }
  }
}

Here the generated type:

export type FrontPageQuery = {
  __typename?: "Query"
  landingFrontPage?: {
    __typename?: "LandingFrontPageRecord"
    name: string
    structuredContent?: {
      __typename?: "LandingFrontPageModelStructuredContentField"
      value: unknown
    } | null
  } | null
}

In my codegen.yml I used the custom scalar types found here: Custom Scalar Types — DatoCMS

Some observations

When I change the JsonField from JsonField: unkown to JsonField: "StructuredText<Record, Record>", in my codegen.yml, in the generated FrontPageQuery type the value will be of type value: StructuredText<Record, Record> which makes TypeScript happy again. Is this the right approach?

Best,
Martin

Hello @martin.palma and welcome to the community!

That is the right approach, but the codegen.yml should have generated as such automatically.
We’ll check this on our end to make sure it doesn’t happen again.

1 Like

I was just running into this issue yesterday. I did try to use the
JsonField: "StructuredText<Record, Record>" in the codegen.yml, which did work for structured text fields. For future travellers I also had to add

      - add:
          content: "import { type Record, type StructuredText } from  'datocms-structured-text-utils';"

to the codegen.yml, borrowed from this solution (changing import names as needed to not have clashes).

However, we also have other JsonField type fields in our models, mostly from plugins which use the generic json field to provide additional data (e.g. Word counter - Plugins — DatoCMS) - and having these typed as Structured Text didn’t work for us. In the end I’ve gone back to using unknown for JsonField, and then casting as StructuredText<Record, Record> after getting the response back.

Potentially Structured Text fields could be typed as a more specific version of JsonField in the api so we can have both?

1 Like

I was able to solve this issue, wrote how I did it in this topic.

1 Like