es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

TypeScript: Tipo genérico de tupla de propiedad de objeto de cierto tipo de valor

Estoy preguntándome si es posible definir un tipo genérico que sea una tupla de longitud 2 [O, K], llamado AccessorPair, donde el primer tipo O es un objeto y el segundo tipo K es una clave de ese objeto, de tal manera que O[K] extienda un cierto tipo T.

Por ejemplo,

const foo: AccessorPair<number> = [new Array(), 'length']
const bar: AccessorPair<boolean> = [[true, false], 0]

Mi primer intento fue

type AccessorPair<t> = T extends (infer O)[infer K] ? [O, K] : never

pero solo lleva al error “Type ‘K’ cannot be used to index type ‘O’.ts(2536)”

Intenté solucionarlo usando

type ValueOf<o, p="" extends="" keyof="" o=""> = O[P]
type AccessorPair<t> = T extends ValueOf<infer o,="" infer="" p=""> ? [O, P] : never

y siempre resuelve a “never”.

¿Es esta definición demasiado vaga para ser soportada por TypeScript? ¿Hay algún concepto de lenguaje de programación que desconozco en relación a esta escritura de tipos? ¡Se agradece cualquier discusión al respecto!</o,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Es posible definir un tipo genérico que sea una tupla de longitud 2 [O, K], llámalo AccessorPair, donde el primer tipo O es un objeto y el segundo tipo K es una clave de ese objeto, de tal manera que O[K] extienda cierto tipo T. Sin embargo, tu primer intento utilizando la palabra clave infer es incorrecto y conduce a un error en TypeScript.

    Para hacer que funcione, puedes usar una restricción de tipo con el operador keyof para asegurarte de que K sea una clave válida de O, y luego usar un tipo condicional para comprobar si el tipo de O[K] extiende T:

    type AccessorPair<t> = [object, keyof any] extends [infer O, infer K]
      ? K extends keyof O
        ? O[K] extends T
          ? [O, K]
          : never
        : never
      : never;
    

    La restricción de tipo [object, keyof any] se utiliza para capturar O y K de una tupla de 2 elementos [O, K] donde O es un objeto y K es una clave de O. Luego, comprobamos si K extiende keyof O para asegurarnos de que K sea una clave válida de O. Finalmente, usamos un tipo condicional para comprobar si el tipo de O[K] extiende T.

    Con esta definición, lo siguiente debería funcionar:

    const foo: AccessorPair<number> = [new Array(), 'length'];
    const bar: AccessorPair<boolean> = [[true, false], 0];
    

    ¡Espero que esto ayude!

Comments are closed.