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

React多语言标签的TypeScript类型优化及Context报错解决

React多语言切换转TypeScript的类型优化与Context类型错误问题

问题背景

原本在ReactJS应用中使用labels.js对象实现多语言切换,代码如下:

export const labelsENG = {
  navSeries: 'shows',
  navHome: 'home',
  navVideo: 'video',
  navGames: 'games',
  navCurrent: 'current',
  navCatchUp: 'shame pile',
  navCommingSoon: 'comming soon',
  navFinished: 'finished',
  formModalHeader: 'Add new Poster',
  modalNoWiki: 'No wiki for ',
  modalCloseButton: 'CLOSE MODAL',
  modalReleased: 'Relased ',
  modalSeenAt: 'You seen it ',
  itemPart: 'Part ',
  itemSeason: 'Season ',
  footerCopyRights: '© 2022 Listownik by Kuba',
  footerHere: 'Footer here',
  error404: 'Error 404 Page Not Happy',
  errorDescribtion: `It's working anyway`,
  posterText: 'Some text',
  shelfSeen: 'Seen'
};

现在要转换为TypeScript,想找比逐个声明字符串属性的接口更高效优雅的类型声明方式,当前使用的接口:

export interface LabelsInterface {
  navSeries: string;
  navHome: string;
  navVideo: string;
  navGames: string;
  navCurrent: string;
  navCatchUp: string;
  navCommingSoon: string;
  navFinished: string;
  modalNoWiki: string;
  modalCloseButton: string;
  modalReleased: string;
  modalSeenAt: string;
  itemPart: string;
  itemSeason: string;
  footerCopyRights: string;
  footerHere: string;
  error404: string;
  errorDescribtion: string;
  posterText: string;
  shelfSeen: string;
}

补充问题:Context类型错误

子组件中为Context的labels声明类型时出错,代码:

const { labels }: LabelsInterface = useContext(LanguageContext);

labels的值为labelsENG或其他语言的labels对象,相关Context代码:

type Language = {
  lang: string;
  setLang: Dispatch<SetStateAction<Language>>;
};

const initialState: Language = {
  lang: languageLabel.eng,
  setLang: (): void => {}
};

const labelInitialState: {} = {
  labels: {},
  setLang: (): void => {}
};

export const LanguageContext = createContext(labelInitialState);

const DataProvider = () => {
 const [lang, setLang] = useState<Language>(initialState);
 const isLanguageEng: boolean = (lang as any) === 'ENG';
 const labels = isLanguageEng ? labelsENG : labelsPL;
 
 return (
      <LanguageContext.Provider value={{ labels, setLang }}>
        <RouteProvider />
      </LanguageContext.Provider>
    );
  };

报错信息

TS2740: Type '{}' is missing the following properties from type '{ navSeries: string; navHome: string; navVideo: string; navGames: string; navCurrent: string; navCatchUp: string; navCommingSoon: string; navFinished: string; formModalHeader: string; modalNoWiki: string; ... 10 more ...; shelfSeen: string; }': navSeries, navHome, navVideo, navGames, and 17 more.

TS2339: Property 'labels' does not exist on type '{ navSeries: string; navHome: string; navVideo: string; navGames: string; navCurrent: string; navCatchUp: string; navCommingSoon: string; navFinished: string; formModalHeader: string; modalNoWiki: string; ... 10 more ...; shelfSeen: string; }'.

解决方案

1. 更优雅的Labels类型声明

不用手动维护接口,直接用typeof基于现有labelsENG自动推导类型,结构更新时类型会同步变化:

// 基于labelsENG自动生成类型
export type LabelsType = typeof labelsENG;

// 其他语言的labels对象直接用这个类型约束,TS会自动校验所有属性是否齐全
export const labelsPL: LabelsType = {
  navSeries: '节目',
  navHome: '主页',
  // 填充剩余翻译属性
};

2. 修复Context类型错误

问题核心是Context的初始状态类型、state类型和使用时的类型不匹配,按以下步骤修正:

第一步:定义Context值的正确类型

import { Dispatch, SetStateAction } from 'react';
import { LabelsType } from './path-to-your-labels-file';

// 明确Context传递的值的类型
type LanguageContextValue = {
  labels: LabelsType;
  setLang: Dispatch<SetStateAction<string>>;
};

第二步:修正初始状态与Context创建

// 初始状态要符合LanguageContextValue类型,空对象占位时加类型断言
const labelInitialState: LanguageContextValue = {
  labels: {} as LabelsType,
  setLang: () => {},
};

export const LanguageContext = createContext<LanguageContextValue>(labelInitialState);

第三步:修正DataProvider中的state类型

原代码中useState的类型错误,lang应该是字符串而非自定义的Language对象:

const DataProvider = () => {
  // 修正state类型,lang是字符串类型
  const [lang, setLang] = useState<string>(languageLabel.eng);
  // 不需要any断言,直接判断字符串
  const isLanguageEng = lang === 'ENG';
  const labels = isLanguageEng ? labelsENG : labelsPL;
 
  return (
    <LanguageContext.Provider value={{ labels, setLang }}>
      <RouteProvider />
    </LanguageContext.Provider>
  );
};

第四步:子组件中正确使用Context

// 直接解构Context值,无需手动指定类型,TS会自动推导
const { labels } = useContext(LanguageContext);
// 之后可直接使用labels.navSeries等属性,类型自动校验

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 03:54:15