反应本机打字稿“字符串”不可分配给“从不”类型的参数。使用中导航

Bat*_*log 56 debugging typescript react-native react-navigation

[我不断收到错误消息,提示“字符串”不能分配给反应本机打字稿中“从不”类型的参数,我不知道为什么。有人可以帮我修复这个错误吗?

先感谢您。

代码图片

代码片段:

const loadReport = (id: string) => {
    setPostId(id);
    navigation.navigate('Report', {postId: id});
}
Run Code Online (Sandbox Code Playgroud)

我在“报告”下看到一条下划线。

Par*_*dev 99

这是一个奇怪的问题,发生在 RN > 0.65 中。我的解决方案:

1.- 进口:

{/* Depends of your Package (Stack or NativeStack...) */}
import { StackNavigationProp } from '@react-navigation/stack';
import { useNavigation } from '@react-navigation/core';
Run Code Online (Sandbox Code Playgroud)

2.- 定义类型

export type RootStackParamList = {
  YourScreen: { id: number } | undefined;
};
Run Code Online (Sandbox Code Playgroud)

3.- 分配类型为 StackNavigationProp 的 useNavigation 挂钩。

const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();
Run Code Online (Sandbox Code Playgroud)

4.- 使用它!(眼睛:使用此类型您可以访问导航对象)

<TouchableOpacity
   // Use this when you pass a parameter (is optional)
   onPress={() => navigation.navigate('YourScreen', {id: 5})}>
</TouchableOpacity>
Run Code Online (Sandbox Code Playgroud)

5.- 请记住以下注意事项:

  • 指定 undefined 意味着该路由没有参数。未定义的联合类型 => AnyType | 未定义意味着参数是可选的。

  • useNavigation const 具有特殊类型,最终类型需要 3 个泛型:

  • 参数列表对象 => RootStackParamList

  • 屏幕路由名称 => RouteName

  • 导航器的 ID(可选)=> NavigatorID

获取自:https://reactnavigation.org/docs/typescript/#annotating-usenavigation

  • 对于 v6,我必须更新导入才能工作:`import { NativeStackNavigationProp } from '@react-navigation/native-stack';` (2认同)

Fré*_*Wat 52

我发现的唯一解决方案是将类型 never 应用于字符串名称。

const goToContent = () => {
    navigate("Content" as never, {} as never);
};
Run Code Online (Sandbox Code Playgroud)

我不确定这是最好的解决方案,但它确实有效。

  • 适合使用一次或两次,在多个地方使用时会产生更多问题, (3认同)
  • OP 没有指定他们正在使用哪个版本的反应导航,但其他一些解决方案比这个更合适,至少对于反应导航 6 来说。 (2认同)

Dan*_*dro 22

简单的解决方案是将 any 添加到 NativeStackNavigationProp 类型

const AppLink = ({
  text,
  screenName,
}: Link) => {

  // pass any to overload 
  const navigation = useNavigation<NativeStackNavigationProp<any>>();

  const handleNavigation = () => {
    navigation.navigate(screenName);
  };  
  
  return (
    <TouchableOpacity onPress={handleNavigation}>
      <Text>{text}</Text>
    </TouchableOpacity>
  );
};

export default AppLink;
Run Code Online (Sandbox Code Playgroud)

  • 我使用 `useNavigation&lt;NativeStackNavigationProp&lt;ParamListBase&gt;&gt;()` 来获得一点额外的类型安全性 (2认同)

lee*_*len 12

useNavigation当不注释并尝试调用navigation.navigate(\'OtherJazzyScreen)`时,我也遇到了以下 ts 错误:

\n
Argument of type \'string\' is not assignable to parameter of type \'{ key: string; params?: undefined; merge?: boolean | undefined; } | { name: never; key?: string | undefined; params: never; merge?: boolean | undefined; }\'\n
Run Code Online (Sandbox Code Playgroud)\n

OP 没有指定他们正在使用哪个版本的反应导航,但你可以在 React Navigation 6 中全局修复这个问题,这意味着你不必直接注释,useNavigation但你仍然可以获得自动完成和类型检查。

\n

摘自 2021 年 8 月的 React-navigation 博客 ( https://reactnavigation.org/blog/2021/08/14/react-navigation-6.0/#better-type-safety ):

\n
\n

在 React Navigation 6 中,您不需要注释useNavigation来获得自动完成和类型检查。这可以通过使用声明合并全局定义屏幕类型来实现:

\n
declare global {   \n  namespace ReactNavigation {\n    interface RootParamList {\n      Home: undefined;\n      Profile: { userId: string };\n      NotFound: undefined;\n    }   \n  } \n } \n
Run Code Online (Sandbox Code Playgroud)\n

您可以在我们的 TypeScript\ndocs 中阅读更多相关信息

\n
\n

React Navigation 6 文档中的另一个示例,如果您已经在其他地方声明了参数:

\n
// E.g. RootStackParamList.ts\nexport type RootStackParamList = {\n  Home: undefined;\n  Profile: { userId: string };\n  NotFound: undefined;\n};\n\n// E.g. App.tsx\nimport { RootStackParamList } from \'path/to/RootStackParamList\';\ndeclare global {\n  namespace ReactNavigation {\n    interface RootParamList extends RootStackParamList {}\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n


rya*_*e28 10

any调用钩子时只需使用类型:

const navigation = useNavigation<any>();
Run Code Online (Sandbox Code Playgroud)

这不是推荐的做法,但它会使代码错误消失。