Вывод типов с учётом локали
Обеспечивайте одинаковую структуру ключей во всех локалях
«Вывод типов с учётом локали» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Вывод типов с учётом локали
Приложение поставляется с несколькими локалями (en, tr, de...). Нам нужен тип, который выдаёт ошибку, если в какой-либо локали отсутствуют ключи, присутствующие в базовой локали, чтобы переводы никогда незаметно не расходились.
Базовая локаль
Выберите одну локаль, обычно en, как эталонную структуру ключей. Все остальные локали должны соответствовать её структуре.
const en = {
greeting: "Hello",
cart: { empty: "Empty", checkout: "Checkout" },
} as const;
type Base = typeof en;Ограничение остальных локалей
Типизируйте каждую дополнительную локаль структурой базовой локали. Теперь отсутствующий ключ становится ошибкой компиляции в файле этой локали.
const tr: Base = {
greeting: "Merhaba",
cart: { empty: "Bo\u015f", checkout: "\u00d6deme" },
};
// Omitting cart.checkout -> Error: property missingОбнаружение лишних ключей
Использование базового типа в качестве аннотации также отмечает неизвестные ключи, которые есть в локали, но отсутствуют в базовой структуре, обнаруживая оставшиеся или неправильно написанные записи.
const de: Base = {
greeting: "Hallo",
cart: { empty: "Leer", checkout: "Kasse" },
extra: "oops", // Error: not in Base
};Вспомогательная функция для определения локалей
Обобщённая вспомогательная функция проверяет структуру, сохраняя каждое значение, и предоставляет удобное место для определения каждой локали.
function defineLocale<T extends Base>(loc: T): T {
return loc;
}
const fr = defineLocale({
greeting: "Bonjour",
cart: { empty: "Vide", checkout: "Paiement" },
});Реестр всех локалей
Соберите локали в записи. Ограничение каждого значения типом Base гарантирует единообразную структуру во всём приложении.
const locales: Record<string, Base> = { en, tr, de: fr };
// every entry must have the full Base key structureРавенство на уровне типов (глубокая проверка)
Для более строгих гарантий можно создать тип SameKeys, который глубоко сравнивает структуры ключей и разрешается в тип ошибки, если они различаются, обеспечивая проверку сверх возможностей обычной аннотации.
type SameKeys<A, B> =
keyof A extends keyof B
? keyof B extends keyof A ? true : false
: false;Однократное получение ключей
Поскольку все локали используют Base, тип путей к ключам из предыдущего урока вычисляется один раз на основе Base и повторно используется для каждой локали, поэтому типизация t не зависит от локали.
type Key = LeafPaths<Base>;
// same valid keys regardless of active localeВыбор локали во время выполнения
Во время выполнения Вы обращаетесь к реестру по активной локали; система типов уже гарантировала, что каждая локаль содержит одинаковые ключи, поэтому обращения безопасны.
function translate(locale: keyof typeof locales, key: Key): string {
return getPath(locales[locale], key);
}Обнаружение отсутствующих ключей во всех локалях
Если нельзя напрямую аннотировать каждый файл, например при импорте JSON, проверка типов во время сборки сравнивает каждую импортированную локаль с Base и показывает тип различий со списком отсутствующих ключей.
type Missing<L> = Exclude<keyof Base, keyof L>;
type TrMissing = Missing<typeof tr>; // never if completeПочему это важно
Локализация без типизации расходится: добавленный в en ключ забывают добавить в de, и приложение выпускает пустую или английскую строку. Ограничение каждой локали общей базовой структурой превращает такое упущение в ошибку компиляции, сохраняя все локали полными и согласованными.
Быстрая проверка
Проверьте своё понимание вывода типов с учётом локали.
Итоги
Вы выбрали базовую локаль как эталонную структуру и ограничили ею все остальные локали, поэтому отсутствие или добавление лишних ключей не позволяет выполнить компиляцию. Вспомогательная функция defineLocale и ограниченный реестр сохраняют структурное единство всех локалей, а пути к ключам один раз выводятся из базовой структуры.
Часто задаваемые вопросы
Урок «Вывод типов с учётом локали» бесплатный?
Да — полный текст урока «Вывод типов с учётом локали» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «Вывод типов с учётом локали»?
Обеспечивайте одинаковую структуру ключей во всех локалях Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Вывод типов с учётом локали»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Типизация ключей переводов
- Типобезопасность интерполяции
- Множественное число с типами
- Вывод типов с учётом локали