¡Hola a todos! Estoy emocionado de hablar sobre el potencial de los Higher Kinda Types para la semántica de las bibliotecas hoy, como parte de la charla relámpago del Congreso de TypeScript 2023. Primero, un poco sobre mí. Mi nombre es Michael Potit. Soy gerente de ingeniería en Volley, donde estamos creando el futuro del entretenimiento habilitado para voz. Tengo pasión por la programación a nivel de tipos. He creado HKT Toolbelt, del cual hablaremos un poco más adelante. Pueden leer sobre mi programación en mi blog en code.lol. Y estoy emocionado de hablar sobre la flexibilidad de los Higher Kinda Types en TypeScript hoy. Entonces, semántica de bibliotecas. ¿Qué queremos decir con esto?
Queremos que el sistema de tipos infiera tanto como sea posible sobre nuestro código. A menudo, las bibliotecas no lo hacen. En este ejemplo de código, estamos usando Lodash. Estamos encadenando algunas operaciones en algún objeto. Estamos calculando las claves y luego mapeando esas claves para convertirlas todas en mayúsculas. Lo que sabemos que el valor debería ser es A, B y C en mayúsculas, pero Lodash solo infiere un array de strings. Esto a veces es muy incómodo y nos obliga a hacer declaraciones de tipos explícitas cuando de otra manera no tendríamos que hacerlo.
Entonces, los HKTs básicamente hacen posible una mejor inferencia. Podemos usar los HKTs para representar operaciones a nivel de tipos y podemos componer tipos juntos utilizando semántica funcional. Podemos hacer esto tan bien que los usuarios finales nunca tienen que escribir ningún tipo personalizado ellos mismos. Entonces, ¿qué son los Higher Kinda Types?
Básicamente, un kind es un tipo asociado con un constructor de tipos. En TypeScript, esto sería como el tipo foo de T es igual a T, ¿verdad? El kind más simple es simplemente star, que son tus tipos base. Y el kind siguiente más simple es star a star, que es tu tipo genérico de aridad uno normal. Entonces, capitalize de S o promise de T, etc. TypeScript admite nativamente estos dos, pero queremos más. Por ejemplo, nos gustaría admitir un tipo que reciba un tipo, genérico en sí mismo, y un valor que represente un array, y queremos iterar sobre ese array aplicando esta operación de tipo a cada elemento. Entonces, el kind asociado con esto sería esta expresión complicada, para la cual necesitamos hacer cosas inteligentes para admitirla en el sistema de TypeScript.
Entonces, ¿qué estamos tratando de hacer realmente? Lo que queremos hacer es escribir código como este, queremos decir que queremos usar este operador, o cualquier tipo de operador de aplicación, y decir, ah, sí. Queremos aplicar la operación capitalize a map, para que obtengamos map capitalize, que convierte capitalize en algo que se puede mapear sobre un array, y luego queremos aplicarlo a un array para obtener un resultado. Estamos extrayendo la lógica intrínseca de iterar sobre un array y aplicar una transformación a cada elemento.
Comments