Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

220
Vistas
How does React Router infer strongly typed arguments from path string?

(This is a question for understanding the workings, not a "how do I..." question)

When working with React Router I've realized that Vscode IntelliSense can suggest me strongly-typed parameters when I type them in a route like this:

<Route path='/users/:userId?' render={props => <UserManager selectedId={props.}/>} />

When I type props.match.params., whenever I have in path string as :text goes as a strongly typed parameter from inside the string to the params as a strongly typed property (and an optional parameter if there is a question mark as in my case):

enter image description here

How can Vscode/TypeScript/React Router generate a strongly typed argument from a bare user-entered string?

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Please see this question just for reference.

You will find explanation in comments:

import React from 'react'

type PathParams<
  Path extends string
  > =
  /**
   * Check whether provided argument is valid route string with parameters 
   */
  (Path extends `:${infer Param}/${infer Rest}`
    /**
     * If yes, call PathParams recursively with rest part of the string 
     * and make it union with current param
     */
    ? Param | PathParams<Rest>
    /**
     * Otherwise, check if argument is standalone parameter, for instance ":userId"
     */
    : (Path extends `:${infer Param}`
      /**
       * If yes, return it
       */
      ? Param
      /**
       * Otherwise check if provided string is allowed route string
       * but without /, for instance "user:userId"
       */
      : (Path extends `${infer _Prefix}:${infer Rest}`
        /**
         * If yes, call recursively PathParams with this parameter
         */
        ? PathParams<`:${Rest}`>
        /**
         * If provided string is invalid - return never
         */
        : never)
    )
  )

/**
 * As you might have noticed, we ended up
 * with union of strings. Now we just need to convert this union
 * into record. It is the easiest part
 */
type Params = PathParams<":siteId/user/:userId">

/**
 * Convert union to record with appropriate keys
 */
type PathArgs<Path extends string> = { [K in PathParams<Path>]: string };

// type Result = {
//     siteId: string;
//     userId: string;
// }
type Result = PathArgs<"/dashboard/:siteId/user:userId">

Now lets try to build similar react component:


type Props<Path extends string> = {
  path: Path,
  params: PathArgs<Path>
}

const Route = <Path extends string>(props: Props<Path>) => {
  return null
}

const jsx = <Route path="/dashboard/:siteId/user:userId" params={{ siteId: 'hello', userId: 'world' }} /> // ok
const jsx_ = <Route path="/dashboard/:siteId/user:userId" params={{ siteId: 'hello' }} /> // error, missing userId prop

Playground

This example should give you a clue how it is done in react router. I know that my example does not reflect 100% same behavior, still I believe it is helpful

Please keep in mind, that my example is much smaller than actual implementation.

Original implementation you can find here with comments. Their implementation is much bigger because there might be a lot of edge cases.

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda