TanStackT
TanStack16mo ago
1 reply
progressive-amaranth

Getting proper `Link` types for own components?

Love the new additions and documentation for createLink(), thanks for the great work!

We have a few different button components, e.g. PillButton, FlatButton, etc. and it supports a tag prop that can be set to any component which will be used to render the button. We've been using it by passing a link:

<PillButton
  tag={Link}
  variant="accent"
  from={fromRoute}
  to="./$action"
  params={{
    action: 'activate',
  }}
  children="Activate"
/>


Where the type for the button is inferred as such (simplified implementation):

type ValidButtonTag = React.ElementType

function PillButton<Tag extends ValidButtonTag = 'button'>(
  props,
  { tag?: Tag }
) {
  const { tag = 'button', ...restProps } = props
  const Component = tag
  return <Component {...restProps} />
}


This works at runtime, but the Link types are never fully inferred and it struggles with resolving
params
/
search
.

The typing is fully correct if we create a "Link" variation with createLink() as such:
export const PillButtonLink = createLink(
  React.forwardRef((props: PillButtonProps<'a'>, ref: any) => (
    <PillButton {...props} ref={ref} tag="a" />
  )),
)


But we ideally want to consume the Buttons as they are, and not have to create a "Link" component variation for each and one of them.

Any idea how we can have TS correctly infer the Link props a la createLink() but with our own components?
Was this page helpful?