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

React Native导航:动态生成页面时navigation.navigate类型报错问题

React Native + TypeScript:动态路由导航的ts(2769)类型错误解决

我在React Native中使用Animated.ScrollView动态生成带导航功能的Page组件,定义了包含Home、ReactQuiz等路由的RootStackParamList,通过遍历routes数组给Page组件传递路由信息,在Page组件的按钮点击事件中调用navigation.navigate(item.route)实现跳转,但触发了TypeScript的ts(2769)类型错误——提示string类型无法匹配RootStackParamList中定义的具体路由名称类型。

相关代码

ScrollView组件

type Props = NativeStackScreenProps<RootStackParamList, "Practice">;

const ScrollView = ({ navigation, route }: Props) => {
  const translateX = useSharedValue(0);
  const scrollHandler = useAnimatedScrollHandler((event) => {
    translateX.value = event.contentOffset.x;
  });
  return (
    <>
      <Animated.ScrollView
        onScroll={scrollHandler}
        scrollEventThrottle={16}
        horizontal
        style={styles.scrollContainer}
      >
        {routes.map((item, index) => {
          return (
            <Page
              key={item.route}
              item={item}
              index={index}
              translateX={translateX}
              navigation={navigation}
              route={route}
            />
          );
        })}
      </Animated.ScrollView>
    </>
  );
};

RootStackParamList定义

export type RootStackParamList = {
  Home: undefined;
  ReactQuiz: undefined;
  LinuxQuiz: undefined;
  Practice: undefined;
  MongoDBQuiz: undefined;
};

routes数组

const routes = [
  {
    route: "LinuxQuiz",
    bgColor: "black",
    fontColor: "yellow",
  },
  {
    route: "ReactQuiz",
    bgColor: "#88dded",
    fontColor: "#1c2c4c",
  },
  {
    route: "MongoDBQuiz",
    bgColor: "#3FA037",
    fontColor: "#4DB33D",
  },
];

Page组件

interface PageProps
  extends NativeStackScreenProps<RootStackParamList, "Practice"> {
  item: {
    route: string;
    bgColor: string;
    fontColor: string;
  };
  index: number;
  translateX: Animated.SharedValue<number>;
}

const Page: React.FC<PageProps> = ({ item, index, translateX, navigation, route }) => {
  return (
    <View>
        <RectangleButton
        onPress={() => navigation.navigate(item.route)}
        >
          {item.route}
        </RectangleButton>
      </View>
  );
};

export default Page;

错误信息

No overload matches this call.
  Argument of type '[string]' is not assignable to parameter of type '[screen: "Practice"] | [screen: "Practice", params: undefined] | [screen: "Home"] | [screen: "Home", params: undefined] | [screen: "ReactQuiz"] | [screen: "ReactQuiz", params: undefined] | [screen: "LinuxQuiz"] | [screen: "LinuxQuiz", params: undefined] | [screen: "MongoDBQuiz"] | [screen: ...]'.
  Overload 2 of 2, '(options: { key: string; params?: undefined; merge?: boolean | undefined; } | { name: "Practice"; key?: string | undefined; params: undefined; merge?: boolean | undefined; } | { key: string; params?: undefined; merge?: boolean | undefined; } | ... 6 more ... | { ...; }): void', gave the following error.
    Argument of type 'string' is not assignable to parameter of type '{ key: string; params?: undefined; merge?: boolean | undefined; } | { name: "Practice"; key?: string | undefined; params: undefined; merge?: boolean | undefined; } | { key: string; params?: undefined; merge?: boolean | undefined; } | ... 6 more ... | { ...; }'.ts(2769)
No overload matches this call.
  Argument of type '[string]' is not assignable to parameter of type '[screen: "Practice"] | [screen: "Practice", params: undefined] | [screen: "Home"] | [screen: "Home", params: undefined] | [screen: "ReactQuiz"] | [screen: "ReactQuiz", params: undefined] | [screen: "LinuxQuiz"] | [screen: "LinuxQuiz", params: undefined] | [screen: "MongoDBQuiz"] | [screen: ...]'.
    Type '[string]' is not assignable to type '[screen: "Practice"] | [screen: "Home"] | [screen: "ReactQuiz"] | [screen: "LinuxQuiz"] | [screen: "MongoDBQuiz"]'.
      Type '[string]' is not assignable to type '[screen: "MongoDBQuiz"]'.
        Type 'string' is not assignable to type '"MongoDBQuiz"'.
  Overload 2 of 2, '(options: { key: string; params?: undefined; merge?: boolean | undefined; } | { name: "Practice"; key?: string | undefined; params: undefined; merge?: boolean | undefined; } | { key: string; params?: undefined; merge?: boolean | undefined; } | ... 6 more ... | { ...; }): void', gave the following error.
    Argument of type 'string' is not assignable to parameter of type '{ key: string; params?: undefined; merge?: boolean | undefined; } | { name: "Practice"; key?: string | undefined; params: undefined; merge?: boolean | undefined; } | { key: string; params?: undefined; merge?: boolean | undefined; } | ... 6 more ... | { ...; }'.ts(2769)

解决方案

问题核心是TypeScript无法识别item.route的具体类型,仅将其视为宽泛的string类型。我们需要给routes数组和Page组件的props添加精确的类型约束:

方法一:提取路由名称联合类型

  1. 从RootStackParamList中导出路由名称的联合类型:
export type RootStackRouteNames = keyof RootStackParamList;
  1. 给routes数组指定类型:
const routes: Array<{
  route: RootStackRouteNames;
  bgColor: string;
  fontColor: string;
}> = [
  {
    route: "LinuxQuiz",
    bgColor: "black",
    fontColor: "yellow",
  },
  {
    route: "ReactQuiz",
    bgColor: "#88dded",
    fontColor: "#1c2c4c",
  },
  {
    route: "MongoDBQuiz",
    bgColor: "#3FA037",
    fontColor: "#4DB33D",
  },
];
  1. 修改Page组件的PageProps类型:
interface PageProps
  extends NativeStackScreenProps<RootStackParamList, "Practice"> {
  item: {
    route: RootStackRouteNames;
    bgColor: string;
    fontColor: string;
  };
  index: number;
  translateX: Animated.SharedValue<number>;
}

方法二:使用as const自动推断精确类型

  1. 给routes数组添加as const断言,让TypeScript自动推断每个route的字面量类型:
const routes = [
  {
    route: "LinuxQuiz",
    bgColor: "black",
    fontColor: "yellow",
  },
  {
    route: "ReactQuiz",
    bgColor: "#88dded",
    fontColor: "#1c2c4c",
  },
  {
    route: "MongoDBQuiz",
    bgColor: "#3FA037",
    fontColor: "#4DB33D",
  },
] as const;
  1. 修改Page组件的PageProps类型,直接复用routes的元素类型:
interface PageProps
  extends NativeStackScreenProps<RootStackParamList, "Practice"> {
  item: typeof routes[number];
  index: number;
  translateX: Animated.SharedValue<number>;
}

两种方法都能让TypeScript确认item.route是RootStackParamList中定义的具体路由名称,而非宽泛的string类型,从而解决ts(2769)类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:05:02