9

With TypeScript 3.9, React Native, React Navigation...

I got error:

interface StackParamList
Type 'StackParamList' does not satisfy the constraint 'Record<string, object | undefined>'.
  Index signature is missing in type 'StackParamList'.ts(2344)

on:

const HomeStack = createStackNavigator<StackParamList>()

In:

const HomeStack = createStackNavigator<StackParamList>()

export interface StackParamList {
  Home: undefined
  Post: { post: Post }
  Category: { category: Category }
  Login: undefined
  ForgotPassword: undefined
  'My profile': undefined
  'My partner': undefined
  Parameters: undefined
  Likes: undefined
  Onboarding: undefined
}

/**
 * Home "stack navigator"
 * @summary this is the navigator for everything located under "home"
 */
export default function HomeStackScreen() {
  return (
    <>
      <StatusBar backgroundColor={colors.background} barStyle="dark-content" />
      <HomeStack.Navigator screenOptions={screenOptions}>
        <HomeStack.Screen
          name="Home"
          component={HomeScreen}
          options={{
            headerTitle: (props) => <Logo {...props} />,
          }}
        />
        <HomeStack.Screen name="Login" component={LoginScreen} />
        <HomeStack.Screen name="Post" component={PostScreen} options={{ headerTransparent: true, title: '' }} />
        <HomeStack.Screen name="Category" component={CategoryScreen} options={({ route }) => ({ title: route.params.category.id })} />
        <HomeStack.Screen name="ForgotPassword" component={ForgotPasswordScreen} />
        <HomeStack.Screen name="My profile" component={UserProfileScreen} options={{ headerTransparent: true, title: '' }} />
        <HomeStack.Screen name="My partner" component={UserPartnerScreen} />
        <HomeStack.Screen name="Parameters" component={UserParamScreen} />
        <HomeStack.Screen name="Likes" component={UserLikesScreen} />
        <HomeStack.Screen name="Onboarding" component={Onboarding} options={{ headerShown: false }} />
      </HomeStack.Navigator>
    </>
  )
}

I don't understand why the interface would not satisfy the type 'Record<string, object | undefined>'.

I don't understand what "Index signature is missing" mean.

Do you have an idea?

Thanks

Xiiryo
  • 3,021
  • 5
  • 31
  • 48

4 Answers4

12

I was able to fix this issue by changing the interface to type. Here's the link to the StackOverflow post.

Error Fix:

// TypeScript Type: Stack Param List
export type StackParamList = {
  Home: undefined
  Post: { post: Post }
  Category: { category: Category }
  Login: undefined
  ForgotPassword: undefined
  'My profile': undefined
  'My partner': undefined
  Parameters: undefined
  Likes: undefined
  Onboarding: undefined
};
jefelewis
  • 1,850
  • 1
  • 27
  • 63
1

context

  • this is needed if you have 'plugin:@typescript-eslint/strict', within your eslint config
  • normally, this work fine if you pass a type, however, if you pass an interface, you need to extends ParamListBase

before

export interface UnAuthStackRoutes {
  debug: undefined;
  'forgot-password': { email: string };
  landing: undefined;
  onboarding: undefined;
  privacy: undefined;
  'sign-up': undefined;
  terms: undefined;
}

after

export interface UnAuthStackRoutes extends ParamListBase {
  debug: undefined;
  'forgot-password': { email: string };
  landing: undefined;
  onboarding: undefined;
  privacy: undefined;
  'sign-up': undefined;
  terms: undefined;
}
ethanneff
  • 3,083
  • 5
  • 23
  • 15
0

Same issue with useParams Hook in React (react-router-dom):

You can't use Interface in Generic for useParams Hook, only type object, if you check useParams in details:

useParams: export function useParams<Params extends {[K in keyof Params]?: string} = {}>(): Params;

If you pay attention on restriction in Generic extends {[K in keyof Params]} you will see that in Interface we can't use computed properties [K in keyof...] but in "type object" we can. That's why there's an error in typescript.

-1

I got this solved by adding:

| Record<string, object | undefined>

On:

export type StackParamList =
  | {
      Home: undefined
      Post: { post: Post }
      Category: { category: Category }
      Login: undefined
      ForgotPassword: undefined
      'My profile': undefined
      'My partner': undefined
      Parameters: undefined
      Likes: undefined
      Onboarding: undefined
    }
  | Record<string, object | undefined>

I still don't really understand why it was needed...

Xiiryo
  • 3,021
  • 5
  • 31
  • 48