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

Next.js+TypeScript+next-intl类型错误:menu1属性不存在于string类型

解决Next.js + TypeScript + next-intl的类型错误问题

问题原因

getMessages()返回的类型默认是string | AbstractIntlMessages,TypeScript无法确定你访问的messages.Menu.menu1属于对象类型,因此抛出类型错误。本地开发模式下类型检查较宽松能运行,但构建时会严格校验导致失败。

解决方案

1. 定义消息结构的TypeScript接口

创建一个类型文件(比如src/types/messages.ts),明确你的多语言消息结构:

export interface Messages {
  Menu: {
    menu1: string;
    // 补充其他菜单项的类型定义
    menu2?: string;
  };
  // 其他消息分组,比如Home、Footer等
  Home: {
    title: string;
  };
}

2. 扩展next-intl的类型定义

创建src/messages.d.ts文件,让next-intl的AbstractIntlMessages继承你的自定义消息类型:

import type { Messages } from './types/messages';

declare module 'next-intl' {
  interface AbstractIntlMessages extends Messages {}
}

3. 为组件Props指定正确类型

在Navigation组件中,明确接收的props类型:

import type { Messages } from '@/types/messages';

interface NavigationProps {
  menuMessages: Messages['Menu'];
}

export default function Navigation({ menuMessages }: NavigationProps) {
  return (
    <nav>
      <a href="/">{menuMessages.menu1}</a>
      {/* 其他菜单元素 */}
    </nav>
  );
}

4. 在Layout中正确传递消息

在layout.tsx中,getMessages()现在会自动推断为你的Messages类型,直接传递即可:

import { getMessages } from 'next-intl/server';
import Navigation from '@/components/Navigation';

export default async function RootLayout({
  children,
  params: { locale },
}: {
  children: React.ReactNode;
  params: { locale: string };
}) {
  const messages = await getMessages();

  return (
    <html lang={locale}>
      <body>
        <Navigation menuMessages={messages.Menu} />
        {children}
      </body>
    </html>
  );
}

5. 验证消息文件结构

确保你的多语言JSON文件(比如messages/en.json、messages/zh.json)的结构和Messages接口完全一致,比如:

// messages/en.json
{
  "Menu": {
    "menu1": "Home"
  },
  "Home": {
    "title": "Welcome"
  }
}

完成以上步骤后,TypeScript的类型错误会消失,构建也能正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:18:18