2

I have problem with mapping in keyof. I'm trying to map over Routes type, but when I map over the object then it breaks conditional params for Route.

type Routes = {
    '/home': {}
    '/pages': {
        pageId: number
    }
}

type IRoute<RouteName, Params> = {
    route: RouteName
} & ({} extends Params ? { params?: Params } : { params: Params })

type Router = {
    [RouteName in keyof Routes]: IRoute<RouteName, Routes[RouteName]>
}

type Route = Router[keyof Router]

Here params should be required but TS ignores it:

const foo: Route = {
    route: '/pages'
    // Missing params: { pageId: number }
}

I need Route type with routeName and params. If params is a generic object then make it optional.

const foo3: IRoute<'/foo', {id: number}> = {
    route: '/foo',
    params: {
        id: 1
    }
}

const foo4: IRoute<'/foo', {}> = {
    route: '/foo'
}

Here's my code. If you call IRoute it works as I expect. But when IRoute is called from mapping through in keyof it breaks and params is optional for all routes.

Here's a TS playground.

MTCoster
  • 5,868
  • 3
  • 28
  • 49

1 Answers1

0

Change your condition from:

{} extends Params ?

to:

keyof Params extends never ?

See the TypeScript Playground.

Karol Majewski
  • 23,596
  • 8
  • 44
  • 53