跳到主要内容
For AI agents: a documentation index is available at /llms.txt

TypeScript

Doura infers state, actions, views, child models, direct query fetch functions, and $queries handles from defineModel(). Use strict or at least noImplicitThis so action and view this types are checked.

State Shape

Use assertions for empty arrays and nullable values:

interface User {
id: string
name: string
}

export const userModel = defineModel({
name: 'user',
state: {
users: [] as User[],
currentUser: null as User | null,
},
})

You can also cast the whole state object:

interface UserState {
users: User[]
currentUser: User | null
}

export const userModel = defineModel({
name: 'user',
state: {
users: [],
currentUser: null,
} as UserState,
})

Public Utility Types

import type {
ModelState,
ModelActions,
ModelViews,
ModelQueries,
ModelModels,
ModelQueryFetches,
ModelInstance,
QueryFetch,
QueryHandle,
Selector,
} from 'doura'

These types derive public API shapes from a model definition:

type UserState = ModelState<typeof userModel>
type UserActions = ModelActions<typeof userModel>
type UserViews = ModelViews<typeof userModel>
type UserQueries = ModelQueries<typeof userModel>
type UserQueryFetches = ModelQueryFetches<typeof userModel>
type UserInstance = ModelInstance<typeof userModel>

Query Inference

Query entries are functions. Doura infers the args tuple and data type from the function signature:

const userModel = defineModel({
name: 'user',
state: { currentUser: null as User | null },
queries: {
fetchUser(ctx, id: string) {
return api.fetchUser(id, { signal: ctx.signal })
},
},
})

type Queries = ModelQueries<typeof userModel>
type FetchUser = Queries['fetchUser'] // QueryHandle<[string], User>

type Fetches = ModelQueryFetches<typeof userModel>
type FetchUserDirect = Fetches['fetchUser'] // QueryFetch<[string], User>

Selectors

React selectors receive ModelAPI and the actions namespace. ModelAPI contains state, views, actions, direct query fetches, and $queries; it does not contain child models or $models.

import type { Selector } from 'react-doura'

const selector: Selector<typeof userModel> = (api, actions) => ({
currentUser: api.currentUser,
refresh: actions.refresh,
})

The same selector type is exported from doura.