Pular para o conteúdo principal

DefaultModelDefinition

The DefaultModelDefinition type is used to correctly type Entry data when requesting it using a StarlightClient.

Without using a DefaultModelDefinition, Entry data will be typed as a “generic” JS object which can hold any kind of data:

import Starlight from '@starlightcms/js-sdk'

// response type will be StarlightItemResponse<Entry> on request success.
const response = await Starlight.posts.entries.get('hello-world')

// helloWorld type is Entry<Record<string, unknown>>. This means that
// `data` can hold anything, which is not type-safe.
const helloWorld = response.data

One way of safely adding type information to Entry objects is by passing a data definition type to the EntrySelector when requesting something:

import Starlight, { VisualField, MediaField } from '@starlightcms/js-sdk'

type PostFields = {
featured_image: MediaField
content: VisualField
}

// response type will now be StarlightItemResponse<Entry<PostsFields>>.
const response = await Starlight.posts.entries<PostFields>.get('hello-world')

// Now, helloWorld type is Entry<PostsFields>.
const helloWorld = response.data

// Which means we can safely access its data, and IDEs will
// auto-complete the data field name below:
console.log(helloWorld.data.featured_image)

Note that we used “Fields” to define our data shape. We recommend using these types, which are exported by this SDK, because they map to the field types available in the Starlight admin when creating models, and should simplify the type definition process. All available Field types are documented in the Data Fields section of this API.

However, passing model definition types around your application is not ideal, and actually unnecessary. Using the DefaultModelDefinition type, all model definitions can be automatically inferred.

To get started, you need to create a type declaration file in which you’ll define all your types. You can name it anything and place it anywhere inside your project, but we recommend naming it starlight.d.ts and placing it in the root folder of your source code, so it can be easily imported later in your application if you ever need to reference these types.

In this file, you can place all your model type definitions (including type definitions for Singleton data, if you want!). Finally, you just need to add a “module definition block” that will tell the SDK which types you expect to receive when requesting models.

Here’s a complete exemple defining two models, Posts and Magazines:

import { StringField, VisualField, MediaField } from '@starlightcms/js-sdk'

type PostFields = {
featured_image: MediaField
content: VisualField
}

type MagazineFields = {
cover_image: MediaField
content: VisualField
issue_number: StringField
issue_year: StringField
}

declare module '@starlightcms/js-sdk' {
export interface DefaultModelDefinition {
// Notice that each key in this interface is a Model slug!
posts: PostFields
magazines: MagazineFields
}
}

After creating this file, types should be automatically inferred without the need to pass these types around:

import Starlight from '@starlightcms/js-sdk'

// response type will be StarlightItemResponse<Entry<PostsFields>>,
// which was implicitly inferred by the SDK!
const response = await Starlight.posts.entries.get('hello-world')

// helloWorld type is Entry<PostsFields>
const helloWorld = response.data

// Auto-complete will work just as before when we explicitly type the Entry!
console.log(helloWorld.data.featured_image)

Hierarchy

  • WorkspaceModelDefinition
    • DefaultModelDefinition