Розробка на TypeScript для проекту 1С-Бітрікс
PHP-шаблони 1С-Бітрікс генерують HTML, а фронтенд-код на «голому» JavaScript у template.php або script.js компонента залишається без типів, без автодоповнення, без захисту від помилок типу «undefined is not a function» у продакшені. TypeScript — прагматичний вибір для будь-якого 1С-Бітрікс-проекту, де JS-коду більше кількох сотень рядків.
Розробка на TypeScript для проекту 1С-Бітрікс
Де живе TypeScript у 1С-Бітрікс-проекті
Два типові сценарії: TypeScript у шаблоні сайту та TypeScript у D7-модулі.
У шаблоні сайту:
/local/templates/my_site/
src/
ts/
catalog.ts
cart.ts
search.ts
scss/
...
dist/ <- скомпільований JS
package.json
tsconfig.json
vite.config.ts
У модулі:
/local/modules/mymodule/
install/
js/
src/ <- TypeScript-вихідники
index.ts
dist/ <- скомпільований JS
package.json
tsconfig.json
tsconfig.json для 1С-Бітрікс-оточення
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler",
"strict": true,
"noUncheckedIndexedAccess": true,
"lib": ["ES2020", "DOM"],
"outDir": "./dist",
"sourceMap": true,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "dist"]
}
noUncheckedIndexedAccess: true — сувора перевірка звернення до масивів за індексом. Важливо для роботи з результатами API 1С-Бітрікс, де поле може бути відсутнім.
Типізація даних 1С-Бітрікс
Перше, що потрібно зробити — описати типи даних, які надходять із PHP-бекенду. 1С-Бітрікс передає дані через JSON у data-атрибутах або AJAX:
// types/bitrix.ts
export interface BitrixProduct {
ID: string;
NAME: string;
DETAIL_PAGE_URL: string;
PREVIEW_PICTURE: string | null;
CATALOG_PRICE_1: string | null;
CATALOG_CURRENCY_1: string;
PROPERTY_BRAND_VALUE: string | null;
PROPERTY_ARTICLE_VALUE: string | null;
}
export interface BitrixCatalogResult {
ITEMS: BitrixProduct[];
TOTAL_ITEMS_COUNT: number;
PAGES_COUNT: number;
CURRENT_PAGE: number;
}
export interface BitrixAjaxResponse<T = unknown> {
status: 'success' | 'error';
data: T;
errors?: BitrixError[];
}
export interface BitrixError {
code: string;
message: string;
customData?: string;
}
1С-Бітрікс повертає числові ID як рядки — "ID": "42", а не "ID": 42. Це потрібно враховувати в типах.
Робота з AJAX-відповідями 1С-Бітрікс
// api/catalog.ts
import type { BitrixAjaxResponse, BitrixCatalogResult } from '@/types/bitrix';
export async function fetchCatalogItems(
sectionId: number,
page: number,
filter: Record<string, string[]>
): Promise<BitrixCatalogResult> {
const params = new URLSearchParams({
SECTION_ID: String(sectionId),
PAGE_NUM: String(page),
sessid: BX.bitrix_sessid(), // CSRF-токен 1С-Бітрікс
action: 'getCatalogItems',
});
Object.entries(filter).forEach(([key, values]) => {
values.forEach(val => params.append(`filter[${key}][]`, val));
});
const response = await fetch('/local/ajax/catalog.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: params.toString(),
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const json: BitrixAjaxResponse<BitrixCatalogResult> = await response.json();
if (json.status !== 'success') {
throw new Error(json.errors?.[0]?.message ?? 'Unknown error');
}
return json.data;
}
BX.bitrix_sessid() — метод ядра 1С-Бітрікс. Щоб TypeScript знав про глобальний об'єкт BX:
// types/globals.d.ts
declare global {
const BX: {
bitrix_sessid(): string;
message(params: Record<string, string>): void;
bind(el: Element, event: string, fn: (e: Event) => void): void;
// ... решта методів за потребою
};
}
export {};
Робота з DOM у шаблонах компонентів
// Типізована робота з data-атрибутами
const catalogEl = document.getElementById('catalog-container');
if (!catalogEl) throw new Error('catalog-container not found');
const rawData = catalogEl.dataset['initialData'];
if (!rawData) throw new Error('No initial data');
// Валідація через Zod або ручна перевірка типів
const initialData: BitrixCatalogResult = JSON.parse(rawData);
Збірка та підключення в шаблоні
Vite збирає TypeScript у /dist/:
// У header.php шаблону
$assetManager = \Bitrix\Main\Page\Asset::getInstance();
$assetManager->addJs(SITE_TEMPLATE_PATH . '/dist/catalog.js');
При розробці — vite dev з HMR, у продакшені — vite build і /dist/ комітиться в репозиторій (або збирається в CI).
Терміни
| Завдання | Терміни |
|---|---|
| Налаштування tsconfig + Vite для шаблону сайту | 4–8 годин |
| Типізація наявного JS-коду (≤500 рядків) | 1–2 дні |
| Розробка нової функціональності одразу на TypeScript | від 1 дня |







