
本文讲解如何修复 react + typescript 中因作用域、类型传递和逻辑结构错误导致的多语言组件失效问题,提供可直接复用的类型安全实现,并指出国际化(i18n)的最佳实践路径。
本文讲解如何修复 react + typescript 中因作用域、类型传递和逻辑结构错误导致的多语言组件失效问题,提供可直接复用的类型安全实现,并指出国际化(i18n)的最佳实践路径。
在构建设计系统时,组件的类型安全性与逻辑内聚性至关重要。原代码存在多个关键问题:getTilte 拼写错误;linguage 变量在 getTitle() 函数体外不可访问(未作为参数传入,也未定义在闭包作用域);独立的 getTitleXx 工厂函数与 TitleProps 类型脱节,且错误地尝试通过扩展运算符({...{ linguage: 'pt-BR' }})向原生 <h1> 标签透传自定义 prop(HTML 元素不接受 linguage 属性,TS 也会报错);最后,getTilte 函数本身未接收参数,却试图访问未声明的 linguage。
以下是重构后的专业级实现——将所有逻辑封装在单一、类型明确的函数组件内,确保类型推导准确、渲染高效、语义清晰:
import React from 'react';
import './title.css';
export type TitleLanguage = 'pt-BR' | 'es-CL' | 'en-US';
export type TitleProps = {
language: TitleLanguage; // 修正属性名:linguage → language(更符合英语习惯)
};
export const Title: React.FC<TitleProps> = ({ language }) => {
// 根据语言返回对应文案
const getText = (): string => {
switch (language) {
case 'pt-BR':
return 'Gerenciamos sua TI com excelência';
case 'en-US':
return 'We manage your IT with excellence';
case 'es-CL':
return 'Gestionamos tu TI con excelencia';
default:
return 'We manage your IT with excellence'; // fallback
}
};
// 根据语言返回对应 CSS 类名
const getClassName = (): string => {
switch (language) {
case 'pt-BR':
return 'storybook-title-portugues';
case 'en-US':
return 'storybook-title--english';
case 'es-CL':
return 'storybook-title--espanol';
default:
return 'storybook-title--english';
}
};
return <h1 className={getClassName()}>{getText()}</h1>;
};✅ 关键改进说明:
- 使用 React.FC<TitleProps> 显式标注函数组件类型,增强 TS 编译时检查;
- 将 linguage 正名为 language,提升可读性与维护性;
- 所有分支逻辑(文案、样式)均基于入参 language 计算,杜绝作用域错误;
- 采用 switch 替代嵌套 if/else,更易扩展新语言;
- 提供 default 分支,避免运行时未定义行为,符合健壮性设计原则。
⚠️ 重要注意事项:
此方案适用于简单场景下的快速验证,但绝不推荐在中大型项目中手动维护多语言映射。真实设计系统应集成成熟的 i18n 方案,例如:
- ✅ 使用 i18next + react-i18next 实现动态语言切换、复数规则、上下文翻译;
- ✅ 配合 @lingui/react 或 formatjs 支持 ICU MessageFormat;
- ✅ 将翻译资源抽离为 JSON 文件,支持设计师/产品经理协作编辑;
- ✅ 结合 Storybook 的 play 功能,为每种语言生成独立的视觉测试用例。
最终,一个可持续演进的设计系统,其组件不仅需“能用”,更要“可维护、可测试、可国际化”。从修复一个 language 参数开始,正是迈向专业工程实践的第一步。


















