Improve Your Frontend Experience With Strapi Types And TypeScript

Web development keeps changing, and it's all about building fast, reliable websites and apps. That's why many developers use tools like Strapi, a headless CMS, and Next.js.


This is a companion discussion topic for the original entry at https://strapi.io/blog/improve-your-frontend-experience-with-strapi-types-and-type-script

Hey, I have opened an issue in this article’s GitHub repo. Basically, it’s very frustrating to try and use nested component data. Also I think that there are still some issues with how the API responds and what the types actually represent (nested data and attribute keys, no arrays where they should actually be). Could be I am using this the wrong way or there’s still some work to do to get everything 100% working. Some examples in the issue that I’ve mentioned.

hi, a few things

  1. if you are working in a monorepo you can create a dev dependency in the frontend module on the strapi module and then import the contentTypes.d.ts. no need to copy the file.
  2. I found some errors in the types.ts file. for example:
    in type MediaValue it should be APIResponse and not APIResponseData
type MediaValue<TAttribute extends Attribute.Attribute> = TAttribute extends Attribute.Media<
  infer _TKind,
  infer TMultiple
>
  ? Utils.Expression.If<TMultiple, APIResponse<'plugin::upload.file'>[], APIResponse<'plugin::upload.file'>>
  : never;

and APIResponseCollectionMetadata is missing the pagination level and should be

export interface APIResponseCollectionMetadata {
  pagination: {
    page: number;
    pageSize: number;
    pageCount: number;
    total: number;
  };
}

it would be very nice if this was part of the Strapi project so that it would be maintained along with the actual types

also media fields should be optional in the type even if they are required in the schema. cause you need to populate the image to get it.

Do you have any idea why the required fields are being typed as possibly undefined?

For example, my collection type attribute start_at is:

start_at: Attribute.DateTime & Attribute.Required;

But typescript is displaying:

(property) start_at: DateTimeValue | undefined

Normally this is something that should be working. Can you give more context on the issue your are having. Also, are you sure that your project is loading types from types found in types/generated/components.d.ts.

Thank you for the awesome feedback. Great tip in point one. On your second point we will update the types.ts accordingly with all your fixes.

Which type are you using exactly that return this undefined value? In any case, even required fields can be undefined when ‘draft and publish’ is enabled.

Hi, can you please explain what should be added to package.json and tsconfig in a monorepo case?

I also struggled with setting up Strapi with TypeScript in a monorepo. To help, I created a starter template that combines Strapi, TypeScript, and Next.js with Turborepo (a monorepo solution from Vercel). It might be just what you’re looking for! :slightly_smiling_face:

Check it out here: GitHub - sawden/turbostrapi: :zap: TurboStrapi: The fast lane to kickstarting Strapi & Next.js projects.

nice. I was looking for something like this.
one quick question, is the api in nextj app type safe?

Hi :slightly_smiling_face:,
The Next.js frontend is more or less type-safe. As you know, Strapi allows you to request only specific fields (e.g., slug and title) via the ‘populate’ parameter in the query URL, even if the content-type has many more fields.
However, the generated types always include all possible fields of the content-type, regardless of what you request in your query!
So while you have the complete type information, the actual data you receive may not include all fields. If you need 100% type safety, I would recommend using GraphQL.