typescriptreact-nativeexpoexpo-router

How can I use a dynamic route in an expo-router Link component using TypeScript?


I have a list of items that I can click to go to different pages. These items are stored in an array. They have the following shape:

type Item = {
  label: string
  path: ItemPath
}

type ItemPath = "/item/one" | "/item/two" | "/item/three"

Where ItemPath is a type I declared with all possible routes for each item.

Then, I'm trying to use the Link component as follows:

import { Link } from 'expo-router'

const items: Item[] = [
  {label: 'one', path: '/item/one'},
  {label: 'two', path: '/item/two'},
  {label: 'three', path: '/item/three'}
]

export default function Page() {
  // ...

  return (
    <View>
      {items.map(item => (
        <Link href={item.path} key={item.label}>
          {item.label}
        </Link>
       )}
    </View>
  )
}

However, the href attribute gives me a TypeScript error:

Type 'ItemPath' is not assignable to type 'StaticRoutes | RelativePathString | http${string}'.

I've tried using <Link href={item.path as RelativePathString} />, but I couldn't find the type. I also spent some time looking for information, but I couldn't find anything relevant to my problem.

I was hoping TypeScript would understand my ItemPath type is a subset of all paths in the app.

How can I fix this?


Solution

  • Solved my problem using Href<T> in the expo-router Link component.

    The code changed as follows:

    import { Link } from 'expo-router'
    
    const items: Item[] = [
      {label: 'one', path: '/item/one'},
      {label: 'two', path: '/item/two'},
      {label: 'three', path: '/item/three'}
    ]
    
    export default function Page() {
      // ...
    
      return (
        <View>
          {items.map(item => (
            <Link href={item.path as Href<itemPath>} key={item.label}>
              {item.label}
            </Link>
           )}
        </View>
      )
    }
    

    Here is the link to the docs