¡Esta es una revisión vieja del documento!
/*
Inicializar un paquete:
npm init -y
Añadir el compilador typescript
npm add -s typescript
Ejecutar el compilador typescript
npx tsc
Inicializar projecto typescript con codigo en src y salida en lib
npx tsc --init --rootdir src --outdir lib
Ahora la ejecución compila el codigo
npx tsc
Dejarlo compilando
npx tsc --watch
*/
let message: string = "Hello world";
console.log(message);
/*
"use strict";
let message = "Hello world";
console.log(message);
*/
//-- Primitives
let isPresent: boolean = true;
let beast: number = 66.4566;
let anotherNumber: string = beast.toPrecision(1);
let notDefined: undefined = undefined;
let notPresent: null = null;
let penta: symbol = Symbol('star');
let biggy: bigint = 9007199254740991n;
//-- List classes
let array: Array<number> = [1, 2, 3];
let array2: number[] = [1, 2, 3];
let set: Set<number> = new Set([1, 2, 3]);
//-- Generics
class Queue<T> {
private data: Array<T> = [];
push(item: T) { this.data.push(item); }
pop(): T | undefined { return this.data.shift(); }
}
let queue: Queue<number> = new Queue();
queue.push(33);
//-- Tuples
let tuple: [number, number] = [0, 0]; // [0, 0, 0] is an error
//-- Types and type alias
let center: {x: number, y: number} = {
x: 0, y: 0
};
type Point = {x: number, y: number};
let center2: Point = {x: 0, y: 0};
//-- Functions
function add(a: number, b: number): number { return a + b; }
function log(message: string): void { console.log(message); }
function sum(...values: number[]) {}
let addFunction: (a: number, b: number) => number;
addFunction = add;
//-- Structural typing
type User = { id: string };
type Product = { id: string };
let user: User = { id: "1" };
let product: Product = { id: "3" } ;
let user2: User = product; // No error
type Point2D = { x: number, y: number };
type Point3D = { x: number, y: number, z: number};
let p2: Point2D = { x: 0, y: 0 };
let p3: Point3D = { x: 1, y: 1, z: 1 };
p2 = p3; // No error. p3 = p2 <- error
function takePoint2D (point: Point2D) {}
takePoint2D(p3);
//-- Classes
class Animal {
private name: string;
protected position: number;
#last_name: string; // This is also private, but `private` is prefered
constructor(name: string) {
this.name = name;
this.position = 0;
this.#last_name = "Toby";
}
public move(meters: number): void { this.position += meters; }
}
class Bird extends Animal { // Having private position would not work
fly (miles: number): void { this.position += (miles * 0.0006); }
}
let cat = new Animal("cat");
cat.move(10);
//-- Any and Unknown
let exampleAny: any = 333;
let exampleUnknown: unknown = 333; // safer
exampleAny.allow.anything();
let bBoolean: boolean = exampleAny;
// exampleUnknown.does.not.allow();
// exampleUnknown.trim(); // does not allow this either
if (typeof exampleUnknown == 'string') { exampleUnknown.trim() }
//-- Type assertion and casts
import { load } from "./test.js" // we require to "allowJS" in tsconfig.json
let varLoaded = load();
const trimmed: string = (varLoaded as string); // assertion
let strVariable: string = "1992";
let numVariable: number = +strVariable; // cast
let bVariable: boolean = (numVariable == 1992);
/*
When you want to use an external variable, like process.env from node. We will do a declaration:
declare const process: any;
There is a way to directly define those external variables in a non invasive way:
- You can set them in `env.d.ts` file.
But if you are going to use node typing, the best way is to install the `@types/node` package.
With this, it is not required to import those variables.
For example, with Express.js: `@types/express`
However, for using TypeScript on node we will make use of ts-node package.
JS:
If you create this class:
class Person {
growOld() { this.whatever }
}
And you use a person instance with: const growOld = person.growOld(), `this` is lost.
For maintaining the `this` context growOld must be defined like this:
class Person {
growOld = () => { this.whatever }
}
*/
//-- Readonly
type XValue = {
readonly x: number;
}
let xvalue: XValue = {x: 33}
// xvalue.x = 33; this gives an error
//-- Unions
function format(input: string | string[]) : void {} // Accepts string or string array
//-- Literals
let direction: 'North' | "South" | "East" | "West";
direction = 'North';
// direction = 'north'; error
class Cat { meow() {}}
class Dog { bark() {}}
type Pet = Cat | Dog;
let pet: Pet = new Cat()
if (pet instanceof Cat) pet.meow();
//-- Discrimination
type Circle = {
kind: 'circle', //This can be a boolean. The real example is with isValid: true, and then isValid: False
validatedValue: string,
};
type Square = {
kind: 'rectangle',
errorReason: string,
};
type Figure =
| Circle
| Square;
function logResult(result: Figure) {
if (result.kind == 'circle') {
console.log('Success, validated value:', result.validatedValue);
}
if (result.kind == 'rectangle') {
console.error('Failure, error reason:', result.errorReason);
}
}
//-- parameter properties
class Person {
constructor (public name: string, public age: number) {}
}
const adam = new Person('Adam', 12000);
console.log(adam.name); // Prints Adam
//-- Intersection types
type Another2D = {
x: number,
y: number
}
type Another3D = Another2D & {
z: number
}
let aP3D = {x: 2, y: 3, z: 4}
type AnotherPerson = { name: string }
type Email = { email: string}
function contact(data: AnotherPerson & Email) {}
contact({name: "hola", email: "a@b.com"})
type ContactData = AnotherPerson & Email;
function contact2(data: ContactData) {}
//-- Optionals
type APerson = {name: string, email: string, phone?: string };
const alfred: APerson = {name: "alfred", email: "a@a.com"}
//-- Not null
type Position = {x: number, y?: number | null | undefined}
let p: Position = {x: 33}
console.log(p.y!)
//-- Interfaces
interface Location2D {
x: number,
y: number
}
interface Location2D { // this is merged
xy: string
}
interface Location3D extends Location2D {
z: number
}
let location: Location3D = {x: 0, y: 0, z: 0, xy: "00"}
//-- never
let example: never;
// ----
type Square1 = {
kind: 'square',
size: number,
};
type Rectangle1 = {
kind: 'rectangle',
width: number,
height: number,
};
type Circle1 = {
kind: 'circle',
radius: number,
};
type Shape1 =
| Square1
| Rectangle1
| Circle1;
function area(s: Shape1) {
if (s.kind === 'square') {
return s.size * s.size;
} else if (s.kind === 'rectangle') {
return s.width * s.height;
} else if (s.kind === 'circle') {
return Math.PI * (s.radius ** 2);
}
const _ensureAllCasesAreHandled: never = s; // this is an assert. It will raise a TS error if we do not handle a type
return _ensureAllCasesAreHandled;
}