Headless WordPress означает, что WordPress служит CMS, а отдельный JavaScript фронтенд (Next.js, Astro, Nuxt и т.д.) рендерит страницы. Фронтенд получает контент через REST API или WPGraphQL и отображает его. Для простого контента — заголовка, аннотации, изображения — типы TypeScript встроены в большинство SDK.
Проблема в пользовательских полях. Пользовательские поля определяются плагинами, а не ядром WordPress. TypeScript не знает, что ваша группа полей «Hero Section» имеет title: string, subtitle: string, background_image: WPImage и cta_button: { text: string; url: string; }. Код фронтенда, который обращается к data.hero_title, не имеет типобезопасности — опечатки, отсутствующие поля и изменения названий полей становятся ошибками во время выполнения.
Решения, которые существовали до Field Forge:
any — противоречит цели TypeScriptField Forge предлагает более простой путь: автоматическая генерация определений TypeScript непосредственно из ваших групп полей.
Вы проектируете группу полей в визуальном редакторе — скажем, «Hero Section» с полями для заголовка, подзаголовка, фонового изображения и кнопки CTA.
На экране администрирования группы полей Field Forge есть кнопка «Скачать TypeScript», которая генерирует файл .d.ts, содержащий определения типов для всех ваших групп полей.
Добавьте файл .d.ts в ваш репозиторий фронтенда (или скопируйте и вставьте в существующий файл типов). Теперь TypeScript знает точную структуру данных каждой группы полей.
«`typescript import { HeroSectionFields } from ‘./types/fieldforge.d.ts’;
function Hero({ data }: { data: HeroSectionFields }) { return (
{data.subtitle}
); } «`
TypeScript ловит опечатки, отсутствующие поля и неправильные типы на этапе компиляции. Автозаполнение IDE работает. Рефакторинг безопасен.
Каждый тип поля Field Forge имеет соответствующий тип TypeScript:
| Поле Field Forge | Тип TypeScript | ||
|---|---|---|---|
| Текст | string |
||
| Текстовая область | string |
||
| Число | number |
||
| Диапазон | number |
||
string |
|||
| URL | string |
||
| Пароль | string (конфиденциальный) |
||
| Изображение | WPImage (встроенный интерфейс) |
||
| Файл | WPFile |
||
| WYSIWYG | string (HTML) |
||
| oEmbed | string (встраиваемый HTML) |
||
| Галерея | WPImage[] |
||
| Выбор (одиночный) | `’option_a’ | ‘option_b’ | ‘option_c’` (литеральный союз вариантов) |
| Выбор (множественный) | `Array<'option_a' | ‘option_b’>` | |
| Флажок | string[] |
||
| Радио | `’option_a’ | ‘option_b’` | |
| Истина/Ложь | boolean |
||
| Группа кнопок | `’option_a’ | ‘option_b’` | |
| Связь | WPPost[] |
||
| Объект поста | WPPost |
||
| Ссылка на страницу | string (URL) |
||
| Таксономия | WPTerm[] или WPTerm (в зависимости от настроек) |
||
| Пользователь | WPUser или WPUser[] |
||
| Выбор даты | string (ISO формат) |
||
| Выбор времени | string |
||
| Выбор цвета | string (hex или rgba) |
||
| Повторитель | Array (вложенный тип) |
||
| Группа | вложенный тип | ||
| Гибкое содержимое | `Array<LayoutA | LayoutB | LayoutC>` (дискриминированный союз) |
| Клонирование | ссылка на клонированную группу |
Сгенерированный Field Forge .d.ts включает вспомогательные типы, которые вы будете использовать на протяжении всего вашего фронтенда:
«`typescript interface WPImage { id: number; url: string; alt: string; width: number; height: number; sizes: { thumbnail: string; medium: string; large: string; full: string; }; }
interface WPFile { id: number; url: string; filename: string; mime_type: string; filesize: number; }
interface WPPost { id: number; title: string; slug: string; content: string; excerpt: string; date: string; modified: string; featured_image: WPImage | null; categories: WPTerm[]; tags: WPTerm[]; }
interface WPUser { id: number; name: string; email: string; avatar: string; }
interface WPTerm { id: number; name: string; slug: string; description: string; } «`
Группа полей под названием «Hero Section» с заголовком, подзаголовком, фоновым изображением и кнопкой CTA генерирует:
«typescript export interface HeroSectionFields { title: string; subtitle: string; background_image: WPImage; cta_button: { text: string; url: string; open_in_new_tab: boolean; }; } «
Использование в компоненте Next.js:
«`typescript import type { HeroSectionFields } from ‘@/types/fieldforge’;
interface Props { hero: HeroSectionFields; }
export function Hero({ hero }: Props) { return (
{hero.subtitle}
<a href={hero.cta_button.url} target={hero.cta_button.open_in_new_tab ? '_blank' : undefined}
{hero.cta_button.text}
); } «`
Каждое свойство типизировано. TypeScript ловит hero.titel (опечатка), hero.background_image.URL (неправильный регистр) и hero.cta_button.open_new_tab (неправильное имя поля) на этапе компиляции.
Поля повторителей становятся Array. Вложенные повторители работают рекурсивно:
«typescript export interface TeamPageFields { team_members: Array<{ name: string; photo: WPImage; bio: string; skills: Array; }>; } «
TypeScript понимает вложенность. Итерация по team_members и затем skills полностью типизирована.
Поля гибкого содержимого генерируют дискриминированные объединения — родная функция TypeScript для обработки массивов с несколькими типами:
«`typescript type HeroLayout = { acf_fc_layout: ‘hero’; title: string; subtitle: string; background_image: WPImage; };
type FeaturesLayout = { acf_fc_layout: ‘features’; section_title: string; features: Array; };
type CTALayout = { acf_fc_layout: ‘cta’; headline: string; button: { text: string; url: string }; };
export interface LandingPageFields { page_sections: Array; } «`
В вашем компоненте фронтенда используйте защиту типов, чтобы отобразить правильный макет:
«typescript function PageSections({ sections }: { sections: LandingPageFields['page_sections'] }) { return ( {sections.map((section, i) => { if (section.acf_fc_layout === 'hero') { return ; } if (section.acf_fc_layout === 'features') { return ; } if (section.acf_fc_layout === 'cta') { return ; } })} > ); } </code>«
Внутри каждого блока if TypeScript сужает section до правильного типа. Приведение типов не требуется.
Когда вы редактируете группы полей в админке Field Forge, типы меняются. Чтобы поддерживать синхронизацию вашего фронтенда:
.d.ts в вашем репозитории фронтендаИли автоматизируйте это через REST API Field Forge:
«`bash
curl https://wp.example.com/wp-json/fieldforge/v1/typescript > types/fieldforge.d.ts «`
Добавьте это в ваш конвейер сборки фронтенда, и типы всегда будут актуальными.
Типы TypeScript не зависят от фреймворка. Сгенерированные Field Forge типы работают с:
Получите Field Forge — от $35/год →
Генерация TypeScript включена в каждый платный план. Ни один другой плагин пользовательских полей WordPress не имеет этой функции.