馃敟 TYPE MANIPULATION, GENERICS (GEN脡RICOS)

Una gran parte de la Ingenier铆a del Software consiste en construir no solo componentes que bien bien definidos y consistentes, as铆 como APIs consistentes. Los componentes que son capaces de trabajar con los datos deben de estar listos para trabajar con los datos del d铆a de ma帽ana.

En lenguajes como C# y Java, una de las principales herramientas es el uso de generics, que es capaz de crear componentes que puedan trabajar con una variedad de tipos y no solo uno solo. Esto permite a los usuarios consumir estos componentes y sus propios tipos.

Hola mundo de los generics

Para arrancar vamos a utilizar el “hola mundo” de los generics; la funci贸n identidad. Esta funci贸n es una funci贸n que retornara cualquiera cosa que sea pasada a ella. Podemos pensar en esta funci贸n como un echo.

Sin los generics, tendr铆amos que escribir una funci贸n identidad para cada uno de los tipos o utilizar el tipo any que cubra todos estos.

function identidad(arg: any): any {
    return arg;
}

Si bien any puede ser utilizado dentro de esta funci贸n para aceptar cualquier tipo, esta decisi贸n tambi茅n implica perder la informaci贸n que es exclusiva del tipo que estamos retornando. Es decir, si enviamos un number o string a la salida el compilador no tendr谩 forma de saberlo.

En su lugar, necesitamos capturar el tipo que se utiliza como argumento de forma que pueda ser utilizar para denotar que valor ha sido retornado. Si enviamos un number, la 煤nica informaci贸n que debe ser retornada es la que es pertinente a este tipo.

function identidad<T>(arg: T): T {
    return arg;
}

Hemos agrega la variable de tipo T para identificar a la funci贸n identidad. Este tipo T permite capturar el tipo que el usuario provee (por ejemplo number), de tal forma que podamos utilizar la informaci贸n despu茅s. Aqu铆, utilizamos T nuevamente para retornar el tipo. Durante la inspecci贸n, podemos ver que utilizamos el mismo tipo como argumento y el tipo retornado. Esto nos permite movernos entre un tipo de informaci贸n de un tipo al de otro.

Ahora podemos entonces que esta versi贸n de la funci贸n identidad es gen茅rica, de forma que puede operar sobre una diversidad de tipos. A diferencia de any, los generics no pierden la informaci贸n del tipo el cual retornan en la salida.

Una vez que hemos escrito la versi贸n generic de identidad, podemos invocarla utilizando de varias formas. La primera es enviando todos los argumentos incluyendo el tipo del argumento.

const salida = identidad2<string>("mi string");

Aqu铆 hemos incluido de forma explicita el tipo T que es un string como uno de los argumentos para la funci贸n a ser invocada.

La segunda forma es la mas com煤n. Enviamos solo el valor y el tipo es interferido, eso quiere decir que T es asignado de forma autom谩tica por el compilador.

const salida2 = identidad2("mi string");

Note que no hemos incluido el tipo de forma explicita dentro de <>; el compilador al ver "mi string" entiende que el tipo es string. Si bien la interferencia puede ser 煤til para mantener el c贸digo mas reducido, en pro de la legibilidad del c贸digo, es una buena idea el especificar el tipo de forma explicita como en el ejemplo anterior.