# TypeScript

> Типы приезжают вместе с подпутём: props, emits, инстанс и токены. Плюс web-types для JetBrains, о котором мало кто знает.

- Page: https://granularity.tech/ru/docs/typescript
- Last reviewed: 2026-10-15

Пакет написан на TypeScript, и типы не собираются в один общий `.d.ts`: у
каждого подпути свой. Импортировали компонент — получили его типы, не потянув
объявления остальных.

## Что экспортирует подпуть компонента

```ts
import {
  GrButton,
  type GrButtonProps,
  type GrButtonInstance,
  type GrButtonTone,
} from '@feugene/granularity/components/GrButton'
```

Рядом с компонентом экспортируются три типа — `GrXProps`, `GrXEmits` и
`GrXInstance`; последний есть у компонентов, которые что-то выставили через
`defineExpose`. Состав держит гейт пакета. Остальные имена —
`GrXConfigurableProps`, `grXConfig`, `grXSafelist` — есть не у всех. Схема имён
при этом одна на все компоненты, и это удобнее списка:

| Тип | Что описывает |
|---|---|
| `GrXProps` | Пропы компонента |
| `GrXEmits` | События — там, где они есть |
| `GrXInstance` | Публичный инстанс — у компонентов, которые что-то выставили наружу |
| `GrXSize`, `GrXTone`, `GrXVariant` | Допустимые значения соответствующего пропа |
| `GrXConfigurableProps` | Подмножество пропов, настраиваемых через `GrConfigProvider` |
| `grXConfig`, `grXSafelist` | Значения, а не типы: конфиг компонента и его safelist для конвейера |

`GrXInstance` пригодится там, где к компоненту обращаются по ссылке:

```vue
<script setup lang="ts">
import { useTemplateRef } from 'vue'
import type { GrDataTableInstance } from '@feugene/granularity/components/GrDataTable'

const table = useTemplateRef<GrDataTableInstance>('table')
</script>
```

Составные компоненты отдают и типы своих данных — у таблицы это `GrDataColumn`,
`GrDataTableRowKey`, `GrDataTableSortDir` и прочее, что иначе пришлось бы
описывать у себя и держать в синхронизации руками.

## Типы, не связанные с компонентами

- `@feugene/granularity/tokens` — справочник токенов как **типизированные
  данные**: `grFoundationTokens`, `grThemeTokens`, `grComponentTokens`,
  `grDerivedTokens` и типы к ним. Источник — те же `tokens/*.json`, из которых
  генерируется CSS, поэтому разойтись с реальными значениями они не могут.
- `@feugene/granularity/directives` — директивы вместе с типами их аргументов.
- `@feugene/granularity/fileValidation` — правила проверки файлов отдельным
  модулем: типы там основная ценность, а не побочная.

:::callout{type="info"}
Справочник токенов намеренно **не** реэкспортируется из корня пакета. Это данные
для документации и инструментов; приложению в рантайме они не нужны, и тянуть их
в основной бандл значило бы нарушить то самое обещание, ради которого всё
затевалось.
:::

## JetBrains: автодополнение из коробки

Пакет собирает и публикует `web-types.json` — формат, который IDE JetBrains
читают сами. Ничего настраивать не нужно: после установки WebStorm, PhpStorm и
IDEA знают компоненты пакета в шаблонах, их пропы со значениями по умолчанию и
описаниями, а также слоты. Событий и
директив в файле нет.

:::callout{type="info"}
Файл объявлен в `package.json` полем `web-types` и лежит в `dist`.
:::

## VS Code и остальные редакторы

| Среда | Что работает |
|---|---|
| VS Code + Vue (Official) | Типы из `.d.ts` и описания из JSDoc |
| Zed, Neovim | То же через Vue LSP; со стороны пакета настраивать нечего |
| JetBrains | Плюс `web-types.json` |

## Настройка проекта

Ничего специфического пакет не требует, но два пункта экономят вечер:

:::steps
1. **`"moduleResolution": "bundler"`** (или `"node16"`) в `tsconfig.json`. При `"node"` TypeScript не читает поле `exports` и не найдёт типы подпутей — импорт компонента подсветится ошибкой, хотя соберётся.
2. **`vue-tsc` вместо `tsc`** для проверки шаблонов. Пакет типизирует слоты и события, и без `vue-tsc` эта часть проверок не выполняется вовсе.
:::

Если типы «не находятся» именно у подпути, а корень импортируется нормально —
это почти всегда первый пункт; разбор с сообщением компилятора есть на странице
[типовых поломок](/ru/docs/troubleshooting).
