or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

content-manager.mdfeatures.mdhooks.mdindex.mdtypes.mdui-components.mdutilities.md

types.mddocs/

0

# Types

1

2

The @strapi/helper-plugin package provides comprehensive TypeScript interfaces and types for Strapi-specific data structures, API responses, component props, and system functionality. These types ensure type safety and developer experience across plugin development.

3

4

## Core Message & Translation Types

5

6

Types for internationalization and message handling throughout the Strapi admin interface.

7

8

```typescript { .api }

9

// Translation message interface extending react-intl

10

interface TranslationMessage extends MessageDescriptor {

11

values?: Record<string, PrimitiveType>;

12

}

13

14

// Base message descriptor from react-intl

15

interface MessageDescriptor {

16

id: string;

17

defaultMessage?: string;

18

description?: string;

19

}

20

21

// Primitive types for translation values

22

type PrimitiveType = string | number | boolean | null | undefined | Date;

23

```

24

25

**Usage Examples:**

26

27

```typescript

28

// Define translatable messages

29

const messages: TranslationMessage = {

30

id: 'plugin.my-plugin.button.save',

31

defaultMessage: 'Save Changes',

32

values: {

33

count: 5,

34

name: 'Article'

35

}

36

};

37

38

// Use with react-intl

39

const { formatMessage } = useIntl();

40

const text = formatMessage(messages);

41

```

42

43

## API Error Types

44

45

Union types for various API error responses that can occur in Strapi applications.

46

47

```typescript { .api }

48

// Union type covering all possible API errors

49

type ApiError =

50

| errors.ApplicationError

51

| errors.ForbiddenError

52

| errors.NotFoundError

53

| errors.NotImplementedError

54

| errors.PaginationError

55

| errors.PayloadTooLargeError

56

| errors.PolicyError

57

| errors.RateLimitError

58

| errors.UnauthorizedError

59

| errors.ValidationError

60

| errors.YupValidationError;

61

62

// Individual error type examples

63

interface ApplicationError {

64

name: 'ApplicationError';

65

message: string;

66

details?: Record<string, any>;

67

}

68

69

interface ValidationError {

70

name: 'ValidationError';

71

message: string;

72

details: {

73

errors: Array<{

74

path: string[];

75

message: string;

76

name: string;

77

}>;

78

};

79

}

80

81

interface ForbiddenError {

82

name: 'ForbiddenError';

83

message: string;

84

details?: Record<string, any>;

85

}

86

```

87

88

**Usage Examples:**

89

90

```typescript

91

// Handle different error types

92

const handleApiError = (error: ApiError) => {

93

switch (error.name) {

94

case 'ValidationError':

95

// Handle validation errors

96

error.details.errors.forEach(validationError => {

97

console.error(`Field ${validationError.path.join('.')}: ${validationError.message}`);

98

});

99

break;

100

case 'ForbiddenError':

101

// Handle permission errors

102

console.error('Access denied:', error.message);

103

break;

104

case 'ApplicationError':

105

// Handle general application errors

106

console.error('Application error:', error.message);

107

break;

108

default:

109

console.error('Unknown error:', error.message);

110

}

111

};

112

```

113

114

## Filter & Query Types

115

116

Types for data filtering, querying, and search operations.

117

118

```typescript { .api }

119

// Attribute-based filters

120

type AttributeFilter = Record<

121

string,

122

Record<EntityService.Params.Filters.Operator.Where, string | null>

123

>;

124

125

// Relation-based filters

126

type RelationFilter = Record<string, AttributeFilter>;

127

128

// Generic filter type

129

type Filter = AttributeFilter | RelationFilter;

130

131

// Filter operator interface

132

interface Operator {

133

value: EntityService.Params.Filters.Operator.Where;

134

intlLabel: MessageDescriptor;

135

}

136

137

// Comprehensive filter data configuration

138

interface FilterData {

139

name: string;

140

metadatas: {

141

label: string;

142

customOperators?: Array<{

143

intlLabel: { id: string; defaultMessage: string };

144

value: string;

145

}>;

146

customInput?: React.ComponentType;

147

options?: Array<{ label?: string; customValue: string }>;

148

uid?: string;

149

};

150

fieldSchema: {

151

type: Attribute.Any['type'];

152

options?: string[];

153

mainField?: {

154

name: string;

155

type?: Attribute.Any['type'];

156

};

157

};

158

trackedEvent?: TrackingEvent;

159

}

160

161

// Default filter input props

162

interface DefaultFilterInputsProps {

163

label?: string;

164

onChange: (value: string | null) => void;

165

options?: FilterData['fieldSchema']['options'] | FilterData['metadatas']['options'];

166

type: FilterData['fieldSchema']['type'];

167

value?: string | null;

168

}

169

```

170

171

**Usage Examples:**

172

173

```typescript

174

// Define filter configuration

175

const articleFilters: FilterData[] = [

176

{

177

name: 'title',

178

metadatas: {

179

label: 'Title',

180

customOperators: [

181

{

182

intlLabel: { id: 'filter.contains', defaultMessage: 'Contains' },

183

value: '$containsi'

184

}

185

]

186

},

187

fieldSchema: {

188

type: 'string'

189

}

190

},

191

{

192

name: 'category',

193

metadatas: {

194

label: 'Category',

195

uid: 'api::category.category'

196

},

197

fieldSchema: {

198

type: 'relation',

199

mainField: { name: 'name', type: 'string' }

200

}

201

}

202

];

203

204

// Create filter objects

205

const titleFilter: AttributeFilter = {

206

title: {

207

$containsi: 'react'

208

}

209

};

210

211

const categoryFilter: RelationFilter = {

212

category: {

213

name: {

214

$eq: 'Technology'

215

}

216

}

217

};

218

```

219

220

## Content Manager Types

221

222

Types specific to content management functionality (also covered in Content Manager documentation).

223

224

```typescript { .api }

225

// Base entity interface

226

interface Entity {

227

id: StrapiEntity.ID;

228

createdAt: string | null;

229

createdBy: User | null;

230

updatedAt: string | null;

231

updatedBy: User | null;

232

}

233

234

// Content type with optional entity fields and dynamic attributes

235

interface ContentType extends Partial<Entity> {

236

publishedAt?: string | null;

237

publishedBy?: User | null;

238

[key: string]: Attribute.GetValue<Attribute.Any> | null;

239

}

240

241

// User interface for content relations

242

interface User extends NonNullableObject<Entity> {

243

firstname?: string;

244

lastname?: string;

245

username?: string;

246

email?: string;

247

isActive: boolean;

248

blocked: boolean;

249

roles: [];

250

}

251

252

// Helper type for non-nullable object properties

253

type NonNullableObject<T> = {

254

[key in keyof T]: NonNullable<T[key]>;

255

};

256

```

257

258

**Usage Examples:**

259

260

```typescript

261

// Work with content types

262

const article: ContentType = {

263

id: 1,

264

title: 'My Article',

265

content: 'Article content...',

266

publishedAt: '2023-01-01T00:00:00.000Z',

267

createdAt: '2023-01-01T00:00:00.000Z',

268

updatedAt: '2023-01-01T00:00:00.000Z'

269

};

270

271

// Type-safe property access

272

const title: string = article.title as string;

273

const isPublished: boolean = !!article.publishedAt;

274

```

275

276

## Component Prop Types

277

278

Common prop interfaces used across UI components.

279

280

```typescript { .api }

281

// Permission-based component props

282

interface CheckPermissionsProps {

283

children: React.ReactNode;

284

permissions?: Array<{ action: string; subject: string }>;

285

}

286

287

// Form component props

288

interface FormProps extends Omit<FormikFormProps, 'noValidate'> {

289

children: React.ReactNode;

290

}

291

292

// Generic input props

293

interface GenericInputProps {

294

type: string;

295

name: string;

296

value?: any;

297

onChange?: (event: { target: { name: string; value: any; type: string } }) => void;

298

error?: string | TranslationMessage;

299

description?: string | TranslationMessage;

300

disabled?: boolean;

301

intlLabel?: TranslationMessage;

302

placeholder?: string | TranslationMessage;

303

required?: boolean;

304

step?: number;

305

max?: number;

306

min?: number;

307

attribute?: any;

308

}

309

310

// Table component props

311

interface TableProps<TRows extends { id: Entity.ID } = { id: Entity.ID }> {

312

children?: React.ReactNode;

313

contentType: string;

314

headers?: Array<TableHeader>;

315

rows?: Array<TRows>;

316

isLoading?: boolean;

317

withBulkActions?: boolean;

318

withMainAction?: boolean;

319

onConfirmDeleteAll?: (ids: Array<TRows['id']>) => Promise<void>;

320

onConfirmDelete?: (id: TRows['id']) => Promise<void>;

321

footer?: React.ReactNode;

322

action?: React.ReactNode;

323

}

324

325

// Table header definition

326

interface TableHeader {

327

name: string;

328

metadatas: {

329

sortable: boolean;

330

label: string;

331

mainField?: { name: string };

332

};

333

fieldSchema?: { type: string };

334

}

335

```

336

337

**Usage Examples:**

338

339

```typescript

340

// Type-safe component props

341

const MyFormComponent: React.FC<FormProps> = ({ children, ...props }) => {

342

return <Form {...props}>{children}</Form>;

343

};

344

345

// Table with typed rows

346

interface Article {

347

id: number;

348

title: string;

349

status: 'draft' | 'published';

350

}

351

352

const ArticleTable: React.FC = () => {

353

const tableProps: TableProps<Article> = {

354

contentType: 'articles',

355

headers: [

356

{ name: 'title', metadatas: { label: 'Title', sortable: true } },

357

{ name: 'status', metadatas: { label: 'Status', sortable: false } }

358

],

359

rows: articles,

360

withBulkActions: true,

361

onConfirmDelete: handleDelete

362

};

363

364

return <DynamicTable {...tableProps} />;

365

};

366

```

367

368

## Hook Return Types

369

370

Types for values returned by custom hooks.

371

372

```typescript { .api }

373

// Fetch client hook return

374

interface FetchClientReturn {

375

get: <TData = any>(url: string, config?: any) => Promise<TData>;

376

post: <TData = any, TResponse = any>(url: string, data?: any, config?: any) => Promise<TResponse>;

377

put: <TData = any>(url: string, data?: any, config?: any) => Promise<TData>;

378

del: <TData = any>(url: string, config?: any) => Promise<TData>;

379

}

380

381

// RBAC hook return

382

interface AllowedActions {

383

[key: string]: boolean;

384

}

385

386

interface RBACReturn {

387

allowedActions: AllowedActions;

388

isLoading: boolean;

389

setIsLoading: () => void;

390

}

391

392

// Selection state hook return

393

interface SelectionActions<TValues> {

394

selectOne: (selection: TValues) => void;

395

selectAll: (nextSelections: TValues[]) => void;

396

selectOnly: (nextSelection: TValues) => void;

397

selectMultiple: (nextSelections: TValues[]) => void;

398

deselectMultiple: (nextSelections: TValues[]) => void;

399

setSelections: (selections: TValues[]) => void;

400

}

401

402

type UseSelectionStateReturn<TValues> = readonly [TValues[], SelectionActions<TValues>];

403

404

// Clipboard hook return

405

interface ClipboardReturn {

406

copy: (value: string | number) => Promise<boolean>;

407

}

408

409

// Query params hook return

410

interface QueryResult<TQuery> {

411

query: TQuery;

412

rawQuery: string;

413

}

414

415

type UseQueryParamsReturn<TQuery> = readonly [

416

QueryResult<TQuery>,

417

(nextParams: TQuery, method?: 'push' | 'remove') => void

418

];

419

```

420

421

**Usage Examples:**

422

423

```typescript

424

// Use typed hook returns

425

const { allowedActions, isLoading }: RBACReturn = useRBAC({

426

create: [{ action: 'create', subject: 'api::article.article' }]

427

});

428

429

// Selection state with typed values

430

interface SelectableItem {

431

id: number;

432

name: string;

433

}

434

435

const [selections, actions]: UseSelectionStateReturn<SelectableItem> = useSelectionState(

436

['id'],

437

[]

438

);

439

440

// Type-safe query parameters

441

interface QueryParams {

442

search?: string;

443

page?: number;

444

sort?: string;

445

}

446

447

const [{ query }, setQuery]: UseQueryParamsReturn<QueryParams> = useQueryParams({

448

page: 1,

449

sort: 'name:asc'

450

});

451

```

452

453

## Context Value Types

454

455

Types for React context values used throughout the plugin system.

456

457

```typescript { .api }

458

// App information context

459

interface AppInfoContextValue {

460

autoReload?: boolean;

461

communityEdition?: boolean;

462

currentEnvironment?: string;

463

dependencies?: Record<string, string>;

464

latestStrapiReleaseTag?: string;

465

nodeVersion?: string;

466

projectId?: string | null;

467

setUserDisplayName: (name: string) => void;

468

shouldUpdateStrapi: boolean;

469

strapiVersion?: string | null;

470

useYarn?: boolean;

471

userDisplayName: string;

472

userId?: string;

473

}

474

475

// Notification context

476

interface NotificationConfig {

477

blockTransition?: boolean;

478

link?: NotificationLink;

479

message?: string | TranslationMessage;

480

onClose?: () => void;

481

timeout?: number;

482

title?: string | TranslationMessage;

483

type?: 'info' | 'warning' | 'softWarning' | 'success';

484

}

485

486

interface NotificationsContextValue {

487

toggleNotification: (config: NotificationConfig) => void;

488

}

489

490

// RBAC context

491

interface Permission {

492

id?: Entity.ID;

493

action: string;

494

actionParameters?: object;

495

subject?: string | null;

496

properties?: {

497

fields?: string[];

498

locales?: string[];

499

[key: string]: any;

500

};

501

conditions?: string[];

502

}

503

504

interface RBACContextValue {

505

allPermissions: Permission[];

506

refetchPermissions: () => void;

507

}

508

509

// Tracking context

510

interface TrackingContextValue {

511

uuid?: string | boolean;

512

deviceId?: string;

513

telemetryProperties?: TelemetryProperties;

514

}

515

516

interface TelemetryProperties {

517

useTypescriptOnServer?: boolean;

518

useTypescriptOnAdmin?: boolean;

519

isHostedOnStrapiCloud?: boolean;

520

numberOfAllContentTypes?: number;

521

numberOfComponents?: number;

522

numberOfDynamicZones?: number;

523

}

524

```

525

526

**Usage Examples:**

527

528

```typescript

529

// Create typed context providers

530

const MyCustomProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {

531

const appInfo: AppInfoContextValue = useAppInfo();

532

const { toggleNotification }: NotificationsContextValue = useNotification();

533

534

const handleAction = () => {

535

if (appInfo.shouldUpdateStrapi) {

536

toggleNotification({

537

type: 'info',

538

message: 'Update available!'

539

});

540

}

541

};

542

543

return (

544

<div>

545

{children}

546

<button onClick={handleAction}>Check Updates</button>

547

</div>

548

);

549

};

550

```

551

552

## Utility Function Types

553

554

Types for parameters and return values of utility functions.

555

556

```typescript { .api }

557

// HTTP client configuration

558

interface FetchClientOptions extends AxiosRequestConfig {

559

signal?: AbortSignal;

560

}

561

562

// Error normalization options

563

interface NormalizeErrorOptions {

564

name?: string;

565

intlMessagePrefixCallback?: (id: string) => string;

566

}

567

568

// Permission checking types

569

type PermissionToCheckAgainst = Pick<Permission, 'action' | 'subject'> &

570

Partial<Pick<Permission, 'actionParameters' | 'conditions' | 'properties'>>;

571

572

// Storage types

573

interface StorageItems {

574

userInfo: UserInfo;

575

jwtToken: string;

576

STRAPI_THEME: 'light' | 'dark';

577

GUIDED_TOUR_CURRENT_STEP: string | null;

578

GUIDED_TOUR_COMPLETED_STEPS: string[] | null;

579

GUIDED_TOUR_SKIPPED: boolean | null;

580

STRAPI_UPDATE_NOTIF: boolean | null;

581

STRAPI_UPLOAD_MODAL_VIEW: 0 | 1 | null;

582

STRAPI_UPLOAD_LIBRARY_VIEW: 0 | 1 | null;

583

videos: unknown;

584

onboarding: unknown;

585

}

586

587

type StorageItemValues = StorageItems[keyof StorageItems];

588

```

589

590

## Event & Tracking Types

591

592

Comprehensive type system for analytics and event tracking.

593

594

```typescript { .api }

595

// Base event without properties

596

interface EventWithoutProperties {

597

name: 'didCreateEntry' | 'didDeleteEntry' | 'didEditEntry' | /* ... many more */;

598

properties?: never;

599

}

600

601

// Events with specific properties

602

interface CreateEntryEvents {

603

name: 'willCreateEntry' | 'didCreateEntry' | 'didNotCreateEntry';

604

properties: {

605

status?: string;

606

error?: unknown;

607

};

608

}

609

610

interface NavigationEvent {

611

name: 'willNavigate';

612

properties: {

613

from: string;

614

to: string;

615

};

616

}

617

618

// Union of all tracking events

619

type TrackingEvent = EventWithoutProperties | CreateEntryEvents | NavigationEvent | /* ... others */;

620

621

// Tracking hook interface

622

interface UseTrackingReturn {

623

trackUsage<TEvent extends TrackingEvent>(

624

event: TEvent['name'],

625

properties?: TEvent['properties']

626

): Promise<null | AxiosResponse<string>>;

627

}

628

```

629

630

**Usage Examples:**

631

632

```typescript

633

// Type-safe event tracking

634

const { trackUsage }: UseTrackingReturn = useTracking();

635

636

// Events without properties

637

trackUsage('didCreateEntry');

638

639

// Events with properties

640

trackUsage('willNavigate', {

641

from: '/admin/plugins',

642

to: '/admin/content-manager'

643

});

644

645

trackUsage('didCreateEntry', {

646

status: 'success'

647

});

648

```

649

650

## Generic & Utility Types

651

652

Helper types for generic operations and type transformations.

653

654

```typescript { .api }

655

// Make all properties of an object non-nullable

656

type NonNullableObject<T> = {

657

[K in keyof T]: NonNullable<T[K]>;

658

};

659

660

// Empty object type

661

type EmptyObject = Record<string, never>;

662

663

// Callback ref type

664

type CallbackRef<T> = (instance: T | null) => void;

665

666

// Axios response wrapper

667

interface AxiosResponseWrapper<T> extends AxiosResponse<T> {

668

data: T;

669

}

670

671

// Generic ID types

672

type EntityID = string | number;

673

674

// Generic entity with ID

675

interface WithId {

676

id: EntityID;

677

}

678

679

// Partial with required ID

680

type PartialWithId<T> = Partial<T> & WithId;

681

```

682

683

**Usage Examples:**

684

685

```typescript

686

// Use generic types for type safety

687

interface MyEntity {

688

id: number;

689

name: string;

690

description?: string;

691

}

692

693

// Ensure all properties are non-null

694

type RequiredEntity = NonNullableObject<MyEntity>;

695

696

// Create partial updates with required ID

697

type EntityUpdate = PartialWithId<MyEntity>;

698

699

const updateEntity = (update: EntityUpdate) => {

700

// update.id is guaranteed to exist

701

// other properties are optional

702

console.log(`Updating entity ${update.id}`);

703

};

704

```

705

706

## Type Integration Best Practices

707

708

### Component Type Safety

709

710

```typescript

711

// Extend base props with additional types

712

interface MyComponentProps extends GenericInputProps {

713

customOption?: boolean;

714

onCustomEvent?: () => void;

715

}

716

717

const MyComponent: React.FC<MyComponentProps> = (props) => {

718

return <GenericInput {...props} />;

719

};

720

```

721

722

### API Response Typing

723

724

```typescript

725

// Define API response shapes

726

interface ArticleListResponse {

727

data: ContentType[];

728

meta: {

729

pagination: {

730

page: number;

731

pageSize: number;

732

pageCount: number;

733

total: number;

734

};

735

};

736

}

737

738

// Use with fetch client

739

const { get }: FetchClientReturn = useFetchClient();

740

const response = await get<ArticleListResponse>('/api/articles');

741

```

742

743

### Error Handling with Types

744

745

```typescript

746

// Create typed error handlers

747

const handleTypedError = (error: unknown) => {

748

if (error && typeof error === 'object' && 'response' in error) {

749

const axiosError = error as AxiosError<{ error: ApiError }>;

750

const normalized = normalizeAPIError(axiosError);

751

752

if (normalized) {

753

console.error(normalized.defaultMessage);

754

}

755

}

756

};

757

```

758

759

The comprehensive type system in @strapi/helper-plugin ensures type safety across all plugin development scenarios, from UI components to API interactions to data management operations.