Skip to content

Input Types

strapi-typed-client generates separate input types for create and update operations. These types reflect what Strapi expects when writing data, which differs from what it returns when reading.

Base Type vs Input Type

When you read data from Strapi, you get the full entity with all computed and populated fields:

ts
// Reading — base type (Article)
{
  id: number
  documentId: string
  title: string
  content: string
  category: { id: number; documentId: string } | null
  tags: { id: number; documentId: string }[]
  coverImage: { id: number; url: string; ... } | null
  createdAt: string
  updatedAt: string
}

When you write data (create or update), you use the input type where relations and media are referenced by ID:

ts
// Writing — input type (ArticleInput)
{
  title: string
  content: string
  category: number | null         // single relation as ID
  tags: number[]                  // many relation as ID array
  coverImage: number | null       // media as ID
}

Relations as IDs

In input types, relations are represented as numeric IDs instead of objects:

Relation TypeInput Type
One-to-onenumber | null
Many-to-onenumber | null
One-to-manynumber[]
Many-to-manynumber[]
ts
await strapi.articles.create({
    data: {
        title: 'New Article',
        category: 5, // link to category with id 5
        tags: [1, 3, 7], // link to tags with ids 1, 3, 7
    },
})

Media as ID

Media fields accept a numeric ID referencing an already-uploaded file in the Strapi media library:

ts
await strapi.articles.create({
    data: {
        title: 'New Article',
        coverImage: 12, // media library file with id 12
    },
})

INFO

File uploads are handled separately through Strapi's upload API. The input type only accepts the ID of an existing media entry.

Components as Objects

Component fields in input types accept plain objects matching the component's input shape:

ts
await strapi.articles.create({
    data: {
        title: 'New Article',
        seo: {
            metaTitle: 'Article about TypeScript',
            metaDescription: 'A deep dive into type safety.',
            keywords: 'typescript, strapi, types',
        },
    },
})

Repeatable components accept an array of objects:

ts
await strapi.articles.create({
    data: {
        title: 'New Article',
        sections: [
            { heading: 'Introduction', body: '...' },
            { heading: 'Conclusion', body: '...' },
        ],
    },
})

Partial Updates

For update(), all fields in the input type are optional. This allows partial updates where you only send the fields that changed:

ts
// Only update the title — all other fields remain unchanged
await strapi.articles.update('abc123', {
    data: {
        title: 'Updated Title',
    },
})

// Clear a relation by setting it to null
await strapi.articles.update('abc123', {
    data: {
        category: null,
    },
})

// Replace all tags
await strapi.articles.update('abc123', {
    data: {
        tags: [2, 4, 6],
    },
})

Nullable Fields

Fields that are not required in your Strapi schema accept null in the input type:

ts
await strapi.articles.create({
    data: {
        title: 'Article', // required — cannot be null
        subtitle: null, // optional — can be null
        category: null, // relation — can be null
        coverImage: null, // media — can be null
    },
})

Full Create Example

Here is a complete example creating an article with all field types:

ts
const result = await strapi.articles.create({
    data: {
        // Scalar fields
        title: 'Getting Started with Strapi v5',
        slug: 'getting-started-strapi-v5',
        content: 'Full article content here...',
        views: 0,
        featured: true,
        publishedAt: '2025-01-15T10:00:00.000Z',

        // Relations (as IDs)
        category: 3,
        tags: [1, 5, 12],
        author: 7,

        // Media (as ID)
        coverImage: 42,

        // Component
        seo: {
            metaTitle: 'Getting Started with Strapi v5',
            metaDescription: 'Learn how to use Strapi v5 with TypeScript.',
        },

        // Repeatable component
        sections: [
            { heading: 'Introduction', body: 'Welcome...' },
            { heading: 'Setup', body: 'First, install...' },
        ],
    },
})

TIP

The generated input types give you full autocomplete, so you do not need to memorize field names or types. Your editor will show you exactly what fields are available and what types they expect.

Released under the MIT License.