Typescript

Typescript es un lenguaje de programación (a modo de “script”) liberado por Microsoft que puede verse como un superconjunto de Javascript con tipos de datos estrictos y posibilita interactúar también con páginas HTML, siendo utilizado también en el desarrollo Web. Con el entorno de programación Deno este lenguaje opera también en el servidor de modo natural (aunque también puede transpilarse a Javascript para Node.js, incluso para GraalVM).

Esta es una referencia ágil para quién tenga nociones de programación o codifique con algún otro lenguaje, también a modo de repaso y uso frecuente. Siendo así, tener esta información como memoria te resultará simple de acceder a los fundamentos, incluso como prueba de concepto sobre el lenguaje.

Ejemplo esencial

function hi(): void {
    console.log("Hi there!");
}

Si conoces javascript puedes notar que la diferencia consiste en que se indica el tipo de la función, en este caso es vacío y se usa void.

Tips esenciales del lenguaje

Para quien tenga habilidades, experticia en programación y/o requiera agilidad en conceptos técnicos, pueden resumirse los siguientes tips esenciales del lenguaje:

  1. Tipos de datos básicos: number, boolean, string, array, object. Las variables se definen simplemente con let y la asignación del valor.
  2. Las funciones se definen con function, luego los parámetros van entre paréntesis (...), continuando con el nombre del parámetro, el caracter : que separa el tipo de datos posteriormente (y separando los parámetros con coma ,). El tipo de datos a retornar va también después de :. Además, se usa return para retornar un valor. También existe una alternativa moderna de expresar funciones (llamada funciones de flecha) que omite la palabra function y en su lugar se usa: () => {...}.
  3. Para el bloque de la función o el flujo de control se usan llaves {}. Las sentencias deben terminar siempre con punto y coma ;.
  4. El flujo de control es semejante a lenguajes como C, Java, Kotlin, Javascript, es decir que se cuenta con una anatomía cercana para el uso de if, for, while, incluso para el manejo de excepciones (try).
  5. El constructor de una clase lleva el nombre constructor y la clase se define con la palabra reservada class y el nombre.
  6. Actualmente, es posible usar operador de nulo seguro (null-safe): ?..
  7. A diferencia de otros lenguajes, el uso de JSON es nativo del lenguaje (siendo básicamente la mezcla entre array y object). Para esto se cuenta con las funciones JSON.stringify y JSON.parse (heredadas de Javascript).

Tipos de datos básicos

Typescript es un lenguaje tipado que toma los tipos de datos primitivos de Javascript, los cuales se asignan a las variables para que sean definidas claramente.

Tipo Descripción
string Cadena de caracteres o texto
number Tipo de datos primitivo para números
boolean Booleano
array Arreglo, se representa como corchetes []
object Objeto, se representa como llaves {}
any Para casos en donde puede aplicar varios tipos
void vacío (para métodos)
null nulo
Date Objeto para fechas

Declaración de variables

Se puede declarar variables con las palabras reservadas let y const, esta última para indicar que el valor no cambia o no es mutable.

Ejemplo:

let variable: string = "Ana";
let list: Array<string> = ["a", "b", "c"];
let age: number: 25;
const inmutable = "Ana";

Definición de funciones

function plus1 (a: number, b: number): number {
    return a + b;
}

const plus2 = (a: number, b: number) => a + b;

Comentarios

// Esto es un comentario de fin de línea

/*
   Este es un comentario de bloque
*/

Condicionamiento if / else (if)

if (i == 1) {
    console.log('one')
}
else if (i == 2) {
    console.log('two')
}
else {
    console.log('aha')
};

El Ciclo For

for (let index = 0; index < list.length; index++) {
    console.log(index);
}
for (ñet item in list) {
    console.log(item);
}

Puede interrumpirse un ciclo con la sentencia break o dar el paso a la siguiente iteración con la setencia continue.

El Ciclo While

while (i < 10) {
    i++;
}
do {
    i++;
}
while (i < 10);

Puede interrumpirse un ciclo con la sentencia break

Evaluador Switch

switch (i) {
    case 1: console.log("one"); break;
    case 2: console.log("two"); break;
    default: console.log("aha");
}

Iteracion forEach

list.forEach(function (item) {
    console.log(item);
})

Excepciones

try {
    ...
}
catch (e) {
    ...
}
finally {
    ...
}

Puedes usar throw (por ejemplo: throw new Error('error!')) para forzar el lanzamiento de un error.

Clases

class Circle extends Shape {
    constructor (radius: Number) {
        this.radius = radius;
    }

    expand (n): Number {
        return super.expand(n) * Math.PI;
    }
}

Intefaces (estructura de datos)

interface PersonModel {
    name: string;
    age: number;
}

Mientras interface define un objeto y su modelo o el tipado de una estructura de datos, existe type que consiste en un alias de un tipo de datos y debe evitarse cualquier confusión. type puede usarse como alias de una interface

Typescript & Node.js

Siendo Node.js un entorno para Javascript y Typescript un superconjunto de Javascript, es posible usar Typescript para Node.js con la debida configuración. Veamos el ejemplo esencial.

function hello(): void {
    console.log('Hi there!');
}

hello();

Guardamos el archivo asignando el nombre: hello.ts

Instalamos el paquete del lenguaje para Typescript bajo Node.js y luego compilamos así:

npm i -D typescript
npx tsc hello.ts
node hello

Proyecto de inicio rapido

Dentro de un directorio de trabajo crearemos una carpeta para nuestro proyecto de código y establecemos el entorno. Veamos:

mkdir project
cd project
mkdir src
npm init

Además, se instalan las dependencias que se usen para el proyecto…

npm i -D typescript
npm i -D concurrently nodemon cross-env rimraf
npx tsc --init
npm i nanoexpress body-parser dotenv
npm i @types/body-parser @types/express @types/node

Un archivo de configuración tsconfig.json, que corresponde al lenguaje Typescript, se ha generado con la línea correspondiente a npx tsc --init. También puede establecerse directamente así:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true
  }
}

Nótese que outDir se establece con el valor dist y sería la única variación requerida.

En archivo package.json incluiremos en el elemento scripts lo siguiente:

"scripts": {
  "serve": "cross-env NODE_ENV=development concurrently \"tsc --watch\" \"nodemon -q dist/index.js\"",
  "start": "cross-env NODE_ENV=production node dist/index.js",
  "preserve": "npm run build",
  "prestart": "npm run build",
  "build": "rimraf dist && tsc",
  "test": "echo \"Error: no test specified\" && exit 1"
},

Nuestro archivo src/index.ts tendrá el siguiente contenido:

import nanoexpress from 'nanoexpress';
import dotenv from 'dotenv';

dotenv.config();

const app = nanoexpress();

app.get('/', (req, res) => {
    return res.send({ status: 'ok' });
});

app.listen(3000);

Para lanzar el servicio ejecutamos:

npm run serve

Incorporando Bases de Datos

Otra manera de iniciar proyectos con Typescript

Usaremos TypeORM y un conector de base de datos, por ejemplo para PostgreSQL, los cuales se podrían instalar así:

npm i typeorm reflect-metadata
npm i pg

Como veremos avanzando, este es un ejemplo alterno y no se ejecutarían esta líneas para el nuevo ejercicio.

Si usaramos el proyecto previamente establecido, modificaríamos el archivo tsconfig.json para asegurar que contenga las siguientes líneas:

"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es5", "es6" ],

Sin embargo, instalaremos TypeORM a nivel global e iniciaremos desde cero el proyecto usando los siguientes comandos:

npm i -g typeorm
typeorm init --name project --database postgres --express --docker
cd project
npm install

project es el nombre de la carpeta del proyecto.
Este comando iniciaría un entorno con Typescript, TypeORM, PostgreSQL, Express, incluso con un archivo de imágen para Docker.

Esto genera también un archivo de configuración para la base de datos denominado ormconfig.json. Deben validarse los parámetros de conexión con la base de datos instalada.

Si iniciamos el proyecto con npm start veremos que el servicio deja disponible para navegar en: localhost:3000/users

Prisma - Tips para conectar tus datos

Una tecnologia mas popular que la anterior (TypeORM) es Prisma. Veamos los aspectos generales de sus nociones y su instalación.

npm i -D prisma
npm i @prisma/client
npx prisma init

El ultimo comando nos genera una carpeta prisma con un archivo schema.prisma

A modo de ejemplo del esquema, considereos el siguiente contenido para el archivo schema.prisma, así:

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "sqlite"
  url      = "file:./mydb.db"
}

model User {
  id       String @id @default(cuid())
  name     String
  email    String
}

Nótese que se especifica sqlite con un archivo. Además, se ha definido un modelo denominado User con unos atributos (id, name, email).

Para obtener nuestro esquema de base de datos ejecutamos lo siguiente:

npx prisma migrate dev

Esta sentencia nos pregunta por un nombre (o sufijo) para la migracion

Para ver la estructura de datos de modo visual podemos ejecutar:

npx prisma studio

Veamos el ejemplo de un bloque de codigo en el que se hace una consulta:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

export const findAllUsers = async () => {
  const users = await prisma.user.findMany({})
  return users
}

prisma corresponde a la conexión, luego user al modelo. Finalmente tendriamos los métodos comunes, tales como findMany, findUnique, create, update y delete.

Typescript en otros entornos (referencias)


© 2019 by César Arcila