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: Utilizar el resultado de un método genérico de una interfaz como entrada para otro método de otra interfaz.

Estoy tratando de hacer una interfaz genérica que reutilice el resultado de un método de interfaz como entrada de otros métodos de interfaz.

Aquí tienes el ejemplo más básico de lo que estoy tratando de lograr:

interface BasicProps<t> {
  input: T;
}

interface TransformProps<t, o=""> {
  transform: (input: T) => O;
  render: <r extends=""></r><this['transform']>>(input: R) => any;
}

type TProps<t, o=""> = BasicProps<t> & TransformProps<t, o="">;

function test<t, o="">(props: TProps<t, o="">) {
  return props.render(props.transform(props.input));
}

const testData = {
  name: 'Jon',
  age: 37,
  ts: true,
  nested: {
    test: 1,
    best: true
  }
};

const testResult = test({
  input: testData,
  transform: (input) => input.nested,
  render: (input) => input.test,
});

Todo parece estar bien hasta que quiero acceder a input dentro del método render, donde parece que R extends unknown, a pesar de que se infiere correctamente al verificar el tipo del método render, que tiene R extends { test: number, best: boolean }.

Mi pregunta es cómo lograr el inferido de tipos de manera que TS acepte input.test dentro del método render e infiera boolean como tipo de resultado de render.
</t,></t,></t,></t,></this[‘transform’]></t,>

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Para lograr la inferencia de tipo deseada, necesitamos cambiar la firma de tipo de la interfaz TransformProps. En lugar de usar ReturnType<this['transform']> para inferir el tipo de retorno del método transform, podemos usar un parámetro de tipo genérico R para representar el tipo de retorno. Luego podemos usar R como el tipo del parámetro de entrada para el método render. Aquí hay un ejemplo de la interfaz modificada:

    interface TransformProps<t, r=""> {
      transform: (input: T) => R;
      render: (input: R) => any;
    }
    

    Con este cambio, la función test puede actualizarse para usar la nueva interfaz de la siguiente manera:

    function test<t, r="">(props: TransformProps<t, r="">, input: T): ReturnType<><t, r="">['render']> {
      const transformed = props.transform(input);
      return props.render(transformed);
    }
    
    const testResult = test({
      transform: (input) => input.nested,
      render: (input) => input.test,
    }, testData);
    

    Ahora el tipo de retorno de test puede ser correctamente inferido como boolean, y podemos acceder a las propiedades del input transformado dentro del método render sin problemas.</t,></t,></t,></t,></this[‘transform’]>

Comments are closed.