Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anterior Revisión previa Próxima revisión | Revisión previa | ||
|
wiki2:new_typescript [2022/11/02 12:13] alfred |
wiki2:new_typescript [2022/11/03 09:30] (actual) |
||
|---|---|---|---|
| Línea 1: | Línea 1: | ||
| ====== TypeScript ====== | ====== TypeScript ====== | ||
| - | <code typescript> | + | * {{ :wiki2:js:typescript:typescript-cheat-sheets.zip |Cheatsheets}}, from [[https://www.typescriptlang.org/cheatsheets]] |
| - | /* | + | |
| - | 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; | + | |
| - | } | + | |
| - | </code> | + | |