react native typescript 'string' 不能分配给 useNavigation 中 'never.' 类型的参数

react native typescript 'string' is not assignable to parameter of type 'never.' in useNavigation

[我一直收到这样的错误:'string' is not assignable to parameter of type 'never' in react native typescript 我不知道为什么。谁能帮我修复这个错误。

提前谢谢你。]1

代码片段:

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

我在 'Report' 下加了一条下划线。

我找到的唯一解决方案是在字符串名称上应用 never 类型。

const goToContent = () => {
    navigate("Content" as never, {} as never);
};

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

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

1.- 进口:

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

2.- 定义类型

export type RootStackParamList = {
  YourScreen: { id: string };
};

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

const navigation = useNavigation<StackNavigationProp<RootStackParamList>>();

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

<TouchableOpacity 
   onPress={() => navigation.navigate('YourScreen', {id: 'smth'})}>
</TouchableOpacity>

我在不注释 useNavigation 并尝试调用 navigation.navigate('OtherJazzyScreen) 时也收到以下 ts 错误:

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; }'

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

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

In React Navigation 6, you don’t need to annotate useNavigation to get autocompletion and type checking. This is possible by defining a type for the screens globally using declaration merging:

declare global {   
  namespace ReactNavigation {
    interface RootParamList {
      Home: undefined;
      Profile: { userId: string };
      NotFound: undefined;
    }   
  } 
 } 

You can read more about it in our TypeScript docs.

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

// E.g. RootStackParamList.ts
export type RootStackParamList = {
  Home: undefined;
  Profile: { userId: string };
  NotFound: undefined;
};

// E.g. App.tsx
import { RootStackParamList } from 'path/to/RootStackParamList';
declare global {
  namespace ReactNavigation {
    interface RootParamList extends RootStackParamList {}
  }
}

简单的解决方案是将 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;