Tipado de parámetros genéricos de TypeScript para funciones currificadas.
Intentando escribir una función curry que tome primero un functor y luego un objeto.
type TestType = {
x: number;
y: number;
hello: string;
};
type CordinateType = {
data: TestType;
id: string;
};
const transform = <t extends="" object,="" k="" extends="" keyof="" t="">(
functor: (val: T[K]) => any
) => (obj: T) =>
Object.entries(obj).reduce((acc, [k, v]) => ({ ...acc, [k]: functor(v) }), {});
const testData: CordinateType = {
id: "uuid-222-uuid",
data: {
x: -3,
y: 2,
hello: "test"
}
};
const positive = (x) => (Number.isInteger(x) ? Math.abs(x) : x);
const result = { ...testData, data: transform(positive)(testData) };
console.log("result", result);
transform
es una función simple que toma un functor y mapea sobre un objeto.
El problema principal es que el tipo de result.data
es {}
, en lugar de TestType
.
Este es un ejemplo de una aplicación de React, la función setState no puede deducir correctamente el tipo.
davy.ai
Escribir una función curried con un functor y un objeto
Problema
Tenemos una función curried llamada
transform
que toma primero un functor y luego un objeto. El objetivo es mapear sobre el objeto y aplicar el functor a cada una de sus propiedades. Sin embargo, el tipo resultante del objeto mapeado es{}
en lugar del tipo deseadoTestType
.Solución
Para asegurar que el tipo resultante del objeto mapeado sea
TestType
, necesitamos ajustar el tipo de la funcióntransform
. En lugar de devolver un objeto plano, podemos devolver un objeto de tipoPartial<t>
y luego hacer un typecast aT
al final.Aquí está la función
transform
actualizada:El tipo de retorno de la función
transform
ahora esT
.Aquí hay una versión modificada de nuestro código de ejemplo con la función
transform
actualizada:Toma en cuenta que pasamos
testData.data
atransform(positive)
ya que solo estamos mapeando sobre la propiedaddata
del objetotestData
.Tipificación del Hook
useState
en ReactEn el segundo código sandbox, tenemos una aplicación de ejemplo de React con un hook
useState
. El problema es que la funciónsetState
del hook no puede deducir el tipo adecuado.Una solución es utilizar un argumento de tipo genérico para definir el tipo de nuestro estado. Aquí tienes un ejemplo:
Observa que usamos
StateType<posttype>
como argumento de tipo genérico para definir el tipo de nuestro estado. Esto ayuda a TypeScript a deducir el tipo adecuado de nuestro estado cuando usamos la funciónsetState
.Conclusión
En resumen, podemos tipificar una función curried con un functor y un objeto ajustando su tipo de retorno, y podemos tipificar el hook
useState
en React utilizando un argumento de tipo genérico para definir el tipo de nuestro estado. Con una tipificación adecuada, podemos hacer que nuestro código sea más robusto y fácil de mantener.