You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让TypeScript合并翻译对象后保留精确类型?

解决next-intl合并翻译后的类型精确化问题

问题背景

使用combineTranslations合并SiteTranslations、AuthFeatureTranslations等翻译模块后,返回值被限定为AbstractIntlMessages这个宽泛类型,丢失了各模块的具体结构信息,导致next-intl无法提供自动补全和类型校验功能。

重构方案

利用TypeScript泛型捕获每个输入翻译模块的具体类型,通过递归交叉类型推导合并后的精确返回类型,替代原有的宽泛类型约束。

具体实现

1. 定义翻译模块类型(示例)

// 站点翻译模块类型
type SiteTranslations = {
  Site: {
    title: string;
    subtitle: string;
  };
};

// 鉴权功能翻译模块类型
type AuthFeatureTranslations = {
  Auth: {
    login: string;
    logout: string;
  };
};

2. 重构combineTranslations函数

import { AbstractIntlMessages } from 'next-intl';

// 递归推导合并后的类型
type CombineTranslations<T extends AbstractIntlMessages[]> = 
  T extends [infer First extends AbstractIntlMessages, ...infer Rest extends AbstractIntlMessages[]]
    ? First & CombineTranslations<Rest>
    : {};

// 类型安全的合并函数
function combineTranslations<T extends AbstractIntlMessages[]>(
  ...translations: T
): CombineTranslations<T> {
  return translations.reduce((acc, curr) => ({ ...acc, ...curr }), {}) as CombineTranslations<T>;
}

3. 使用示例

// 具体翻译内容
const siteTranslations: SiteTranslations = {
  Site: {
    title: '首页',
    subtitle: '欢迎访问'
  }
};

const authTranslations: AuthFeatureTranslations = {
  Auth: {
    login: '登录',
    logout: '退出'
  }
};

// 合并后获得精确类型
const combinedTranslations = combineTranslations(siteTranslations, authTranslations);

// 支持自动补全与类型校验
combinedTranslations.Site.title; // ✅ 正常提示
combinedTranslations.Auth.login; // ✅ 正常提示
combinedTranslations.Site.invalidKey; // ❌ 类型报错,符合预期

关键说明

  • 泛型CombineTranslations通过递归解构输入数组的类型,将每个翻译模块的类型进行交叉合并,最终得到包含所有模块结构的精确类型。
  • 类型断言as CombineTranslations<T>用于告诉TypeScript,reduce合并后的结果符合推导的精确类型(因为reduce的默认返回类型无法自动识别交叉合并后的结构)。
  • 所有输入的翻译模块必须符合AbstractIntlMessages约束,确保与next-intl的类型体系兼容。

内容的提问来源于stack exchange,提问作者Joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:12:28