-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSpanish.ts
583 lines (475 loc) · 21.6 KB
/
Spanish.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
/*
Este archivo esta pensado para verlo coloreado y con los errores
correspondientes, asi que conviene descargarlo y abrirlo con un
editor compatible con TypeSciprt como por ejemplo el VS Code.
*/
/////////////////////////////// QUE HAY EN ESTE DOCUMENTO Y ¿QUE CARAJO ES TYPESCRIPT? ////////////////////////////
/*
Este documento hace un recorrido muy rapido por todas las cosas que hay que saber para poder trabajar con
Typescript, en una hora se puede aprender si se le ponen ganas y se enseña bien.
Todos los lenguajes incluyendo las ultimas versiones de PHP y Python tienen "tipado estatico", osea son como
TypeScript, solo faltaba que JavaScript tenga esta funcionalidad que es indispensable en un lenguaje de calidad.
Usan Typescript: Google, Github, Facebook, Microsoft y casi todas las empresas conocidas.
El tipado estatico nos obliga a escribir el tipo de cada variable que creamos, esto es una información extra en
el código que permite que el editor entienda mucho mejor nuestro codigo y nos pueda ayudar con autocompletado de
calidad, funcionalidades de automatizacion de trabajo que no sabias que existian en el editor, señalamiento de
bugs mientras se escribe, etc, etc.
Esto implica que estamos escribiendo una documentación implicita (obligatoria) que tambien sirve para poder leer
mejor nuestro codigo sin tener que abrir archivos y documentaciones para saber como proceder con un codigo que
no es nuestro o que no recordamos.
Asi que todo el tiempo extra que necesitamos para escribir lo que Typescript nos obliga, nos lo devuelve
multiplicado mas tarde en bugs que no tenemos que arreglar y en las demas ventajas antes explicadas, no consume
tiempo si no todo lo contrario.
Typescript funciona igual que babel: Procesa nuestro codigo y genera un Javascript comun, se instala como un
plugin de webpack. Asi que es 100% compatible con todos los navegadores por que no esta presente en la ejecucion
final en el navegador, es una herramienta para usar mientras se programa.
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////// ANTES DE EMPEZAR //////////////////////////////////////////////
/*
1) Ejecutar el comando: npm install typescript tslint -g
2) Instalar el plugin TSlint para Visual Studio Code o para el editor que uses
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////// LO PRINCIPAL /////////////////////////////////////////////////////
/*
La diferencia entre Typescript y Javascript es que hay que escribir los tipos al crear una variable o una funcion,
por ejemplo:
*/
const palabraDeSaludo: string = "hola";
function saludo(nombre: string): string { // Aca especificamos el tipo del parametro y que tipo devuelve la funcion.
return palabraDeSaludo + " " + nombre;
}
/*
La gracia de escribir el tipo es que el contenido que le asignas a la variable tiene que ser del tipo que escribiste,
de lo contrario nos va a dar un error.
Los tipos que se pueden poner son estos:
*/
string // Para los strings (los tipos basicos van en minuscula)
number // Para los numeros
boolean // Para los booleanos
Array<TIPO_DEL_CONTENIDO> /* o tambien puede ser: */ TIPO_DEL_CONTENIDO[] // Para los arrays
void // Se usa solo para indicar que algo no devuelve nada.
(a:string, b:string)=>void // Ejemplo de un tipo para una funcion o una arrow function, (si, es largo de escribir).
NombreDeClase // Para la instancia de una clase el tipo es el mismo nombre de la clase.
NombreDeInterfaz // Ver mas abajo que son las Interfaces
NombreDeEnum // Ver mas abajo que son los Enums
any // NO HAY QUE USARLO, desactiva el tipado, si sentis que es la unica solucion a un problema es por que algo esta mal o te falta aprender algo.
object // NO HAY QUE USARLO, sirve para los objetos, igual que el any es un tipo sin informacion por lo tanto es inservible y anti-tipado.
/*
Tipos literales:
*/
/*
En el siguiente ejemplo la variable saludo no solo tiene que ser un string si no que el string
tiene que decir "hola", de lo contrario nos da error.
*/
let saludo1: "hola" = "chau"; // Da error
let saludo2: "hola" = "hola"; // Funciona
/*
Otro ejemplo con numeros:
*/
let cero: 0 = 0;
/*
Otro ejemplo con un objeto:
*/
let ejemplo2: {valor1: string, valor2: number} = {valor1: "hola", valor2: 666};
/*
Los tipos literales se vuelven largos e ilegibles muy facilmente, para solucionar eso existen las
interfaces y los enums, de esa manera podemos escribir el tipo aparte y ponerle un nombre que se
usa como el tipo. Mas abajo esta explicado en mas detalle.
*/
/*
Typescript agrega una cosa mas, los modificadores de acceso, private y public, esto sirve para que una
propiedad de una clase no pueda ser leida desde afuera (private) o si pueda (public, es lo que viene por
defecto en javascript). Mas abajo hay una explicacion detallada.
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// EJEMPLO DE UNA CLASE ESCRITA CON TYPESCRIPT //////////////////////////
export class Employee implements IExample
{
private department : string | number; // Se puede poner como tupo mas de un tipo a la vez separado por | , esto se llama: "Union Types".
public _list : string[]; // Los arrays son tipados, solo pueden contener elementos del tipo indicado
public list2 : Array<string>; // La otra sintaxis del tipo array.
public myEvent : (x: number, y: number) => void; // Function types
constructor(yourName: string, department: string | number) // En el constructor no se escribe que tipo devuelve.
{
this.department = department;
}
public example(): string
{
return `Hello, I work in ${this.department}.`;
}
/*
Getter
*/
get superList(): Array<string>
{
return this._list;
}
/*
Setter
*/
set superList(newList: Array<string>) : void
{
this._list = newList;
}
/*
Union Types en uso:
*/
public unionTypesUsageExample(param: string | number | HTMLElement | HTMLImageElement | HTMLDivElement): void
{
/*
Se usa typeof para los tipos basicos (string y number) y se usa instanceof para los demas tipos
(de todas maneras esto es un dato de JS no esta relacionado con TS):
*/
if (param instanceof HTMLDivElement) {
console.log('this is HTMLDivElement');
} else if (param instanceof HTMLImageElement) {
console.log('this is HTMLImageElement');
} else if (param instanceof HTMLElement) {
console.log('this is HTMLElement');
} else if (typeof param === "string") {
console.log('this is string');
} else if (typeof param === "number") {
console.log('this is number');
} else {
console.log("You're not supposed to be here!");
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// MODIFICADORES DE ACCESO /////////////////////////////////////////////
/*
Nos permite hacer que una clase tenga una especie de api publica y privada para que no se acceda ni se
haga autocompletado de cosas que no hay que llamar desde afuera.
*/
export class Person
{
private id : number; // private hace que la propiedad solo sea visible dentro de la clase
protected name : string; // protected hace que la propiedad sea solo visible dentro de la clase y clases hijas
public nickname : string // public deja que la propiedad sea visible desde afuera como es comun en JS, tambien es
// la default si no se escribe el modificador de acceso.
// Los modificadores de acceso en los parametros del constructor crean parametros y propiedades a la vez
constructor(private lastName: string, name: string)
{
this.name = name; // Usando un modificador de acceso en la propiedad del constructor nos ahorramos este tipo de lineas.
}
private saludar():void // Tambien se usan en los metodos, observar el private aca antes del nombre del metodo.
{
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////// INTERFACES ///////////////////////////////////
/*
Como vimos antes con los tipos literales, se pueden escribir las keys de un objeto con su tipo como el
tipo del objeto asi:
*/
let ejemplo: {valor1: string, valor2: number} = {valor1: "hola", valor2: 666};
/*
Pero un tipo no puede ser tan largo por una cuestion de legibilidad, de hecho es una muy mala practica
escribir un tipo literal asi. Asi que se lo puede escribir aparte con un nombre y usar ese nombre como
el tipo, asi queda mas legibley es reautilizable, eso son las interfaces.
*/
/*
Declarar una interfaz:
*/
interface IExample // Las interfaces se usa escribirlas con una I adelante del nombre.
{
name: string; // Ejemplo de propiedad obligatoria (si no esta presente en el objeto tira error)
color?: string; // Ejemplo de propiedad opcional (es con el signo de interrogación)
walk?(): number; // Ejemplo de metodo obligatorio.
getHairType?(): number; // Ejemplo de metodo opcional.
}
/*
Utilizar la interfaz con una variable:
*/
const miObjeto: IExample = {color: "red", walk: () => 200} // Error: falta la propiedad "name"
/*
Ademas se pueden aplicar a claseses, con la palabra implements, esto obliga a la clase a que
implemente lo que esta en la interfaz.
De esa manera el nombre de la interfaz puede ser usado como el tipo para las instancias de la
clase y tambien vale para todas las clases que implementen la interfaz haciendolas compatibles
en el tipado, por ejemplo la interfaz IMascota se puede usar como tipo para
las instancias de Perro y Gato (siempre que ambas implementen la interfaz IMascota).
Para esto se usa la palabra "implements":
*/
class MiClase implements IExample {} // Error: No implementamos las propiedades de IExample en la clase
/*
Como las propiedades de una clase se escriben con su tipo no hace falta que las clases implementen
si o si una interfaz, pero si hace falta que todos los objetos escritos utilizando {}, deberian
tener su interfaz.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////// ENUMS //////////////////////////////////////////////////////
/*
Como vimos antes una variable puede tener varios tipos simultaneamente y pueden ser tipos
literales, por ejemplo:
*/
const direccion: "left" | "right" | "top" | "down" = "left";
/*
Esta variable es un string que puede tener esos 4 valores, pero se hace muy largo de leer,
para solucionar eso estan los enums.
*/
/////// Declaración:
enum Direction {
Up,
Down,
Left,
Right,
}
/////// Ejemplos de uso:
const whereToGo: Direction = Direction.Left;
exampleInMethod(Direction.Left);
function exampleInMethod(newDirection:Direction)
{
if(newDirection == Direction.Left)
console.log("going left");
}
/*
El transpilador transforma los usos del enum en numeros, se puede especificar que numeros queremos
para cada elemento del enum (es raro que se necesite):
*/
enum Directions {
Up = 0,
Down = 1,
Left = 2,
Right = 3
}
///////// También se pueden hacer "string enums":
enum Directions2 {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////// GENERICS //////////////////////////////////////////////////
/*
Este es el último concepto y el mas complicado de aprender aveces.
Es para que nunca sea necesario usar los tipos "any" u "object", caundo si o si necesitas esos
tipos es por que tenes que recurrir a esto.
Esta herramienta permite crear metodos o clases donde le pasamos el tipo entre los caracteres < >
e internamente trabaja con ese tipo sin importar cual sea.
*/
/**
* Declarar:
*/
function randomizeArray<T>(array: Array<T>): Array<T>
{
/*
Esta funciona mezclaria un array, no importa de que tipo es
por que no nos metemos con los elementos.
*/
return array;
}
/**
* Usar:
*/
const randomized: Array<string> = randomizeArray<string>(["Frutilla", "Chocolate"]);
/*
Si no usaramos esto, el método habría que escribirlo asi:
function randomizeArray(array: Array<any>): Array<any>
Perderiamos la informacion del tipo, "any" no es bueno por que no contiene ninguna información.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////// PARTIAL ///////////////////////////////////////////////////
/*
En react usamos la funcion: this.setState(state) que acepta un objeto que tenga alguna de las propiedades
del state, si le pasas un objeto que no tiene ninguna propiedad del state nos da error o si tiene alguna
propiedad que no esta en el state tambien nos da error, la pregunta es, como sabe typescript esto?.
Es un tipo que viene con typescript que se llama Partial<>:
*/
let parteDelObjeto1: IExample = { // Error: IExample tiene la propiedad "name" como obligatoria y no la estamos poniendo.
color: "Black"
}
const parteDelObjeto2: Partial<IExample> = { // Aca no tenemos mas ese problema. Con que tenga alguna propiedad de IExample esta bien.
color: "Black"
}
const parteDelObjeto3: Partial<IExample> = { // Error: la propiedad sarasa no esta en IExample.
sarasa: "Hola"
}
/*
Esto es muy util tanto en React como en cualquier otro codigo que incorpora el patron inmutability.
Hay mas tipos que vienen con Typescript para hacer otras cosas pero son poco comunes.
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////// CAST ////////////////////////////////////////////////
/*
Se le llama castear cuando se quiere hacer pasar un tipo por otro, si son compatibles nos los va
a permitir, los tipos compatibles son las clases padres con sus clases hijos o las clases que
implementan una interfaz.
Se puede castear con 2 sintaxis, una sirve para cuando la otra tira error de sintaxis por culpa
del contexto o para cuando se quiere dejar mas legible el codigo, funcionalmente son
identicas en TS.
*/
/*
Sintaxis 1
*/
hacerAlgo((ClaseHijo)instanciaClasePadre);
/*
Sintaxis 2
*/
instanciaClaseHijo as ClasePadre
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////// USAR UNA LIBRERIA ESCRITA EN JS /////////////////////////////////////
/*
Se pueden usar librerias hechas en JS como si estuvieran hechas en TS, la comunidad escribe archivos
con extensión .d.ts que son definiciones de tipos para librerias de JS, hay muchas escritas y ya casi
todo se encuentra. En otras palabras esto le agrega los tipos a una libreria que no los tiene.
Para agregarle los tipos a una libreria hacemos lo siguiente:
1) npm install, con el nombre de la libreria agregandole el prefijo @types/ por ejemplo:
npm install @types/react
2) Si nos dice que no existe el paquete puede ser que sea por que la libreria ya esta programada en
TypeScript y no necesitamos los tipos aparte por que vienen ya, en ese caso no tenemos que hacer
nada y simplemente vemos el tipado.
3) Si no tuvimos suerte con ninguno de los puntos anteriores y no tenemos los tipos entonces podemos
usar la libreria sin los tipos, (ver instrucciones para eso abajo).
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// USAR UNA LIBRERIA EN JS QUE NADIE ESCRIBIO LOS TIPOS ////////////////////////
/*
Para eso hay que agregar en el import, un comentario con el texto @ts-ignore, asi:
*/
// @ts-ignore
import { LibraryObject } from "example-library";
/////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// CREAR LOS TIPOS DE UNA LIBRERIA EN JS /////////////////////////////////
/*
El proceso para crear una definicion de tipos .d.ts es bastante automatizado, no requiere mucho
tiempo, mas detalles en este link:
https://stackoverflow.com/questions/12687779/how-do-you-produce-a-d-ts-typings-definition-file-from-an-existing-javascript
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// CONVERTIR JSON EN UNA INTERFAZ ///////////////////////////////////
/*
Cuando recibimos un json y lo parseamos a un objeto, necesitamos el tipo para ese objeto,
concretamente necesitamos la interfaz. Esto puede ser una tarea tediosa de hacer a mano,
en esta aplicacion web pegamos el json y nos genera las interfaces bien hechas:
https://jvilk.com/MakeTypes/
*/
/////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////// INSTALACION: EN UN PROYECTO CON NODE.JS ///////////////////////////////
/*
1) Creamos una carpeta vacia y abrimos la carpeta con el VS code.
2) Ejecutar en la consola: npm init -y
Eso crea el archivo package.json, si la carpeta tiene un espacio en el nombre nos puede tirar error.
3) Abrimos package.json y reemplazamos la linea del valor main por la siguiente:
"main": "./build/index.js", (O la ruta donde va a ir el index.js)
4) Ejecutar en la consola el siguiente comando:
npm install --save-dev typescript @types/node tslint
5) Crear archivo tsconfig.json y pegar el sigueinte codigo:
*/
{
"compilerOptions": {
"outDir": "./build",
"rootDir": "./src",
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"watch": true
}
}
/*
6) Crear src/index.ts, ahi vamos a arrancar a programar nuestra aplicacion.
7) El comando para compilar typescript en todo el proyecto y que se quede vigilando
los cambios es: tsc
Asi que tiene que estar incluido en el comando npm start
8) Crear un archivo tslint.json con este contenido:
*/
{
"extends": ["tslint:latest"],
"rules": {
"no-console": {
"severity": "warning",
"options": [
"debug",
"info",
"log",
"time",
"timeEnd",
"trace"
]
},
"typedef": [
true,
"call-signature",
"parameter",
"property-declaration",
"variable-declaration",
"member-variable-declaration",
"object-destructuring",
"array-destructuring"
],
"no-var-requires": false,
"ordered-imports": false,
"no-empty-interface": false,
"object-literal-sort-keys": false,
"no-eval": false,
"no-trailing-whitespace": false,
"no-shadow": ["error", { "builtinGlobals": false, "hoist": "never", "allow": [] }],
"no-submodule-imports": false,
"no-implicit-dependencies": false
},
"jsRules": {},
"rulesDirectory": []
}
/*
Con eso ya se puede empezar a programar.
Para tener en cuenta:
- Para iniciar el server ejecutar este comando:
node ./build/index.js (o la ruta donde esté el index.js)
- Para iniciar una sesion de debug que permite poner breakpoints:
Presionar F5 y seleccionar Node.js (no puede estar corriendo el server)
*/
////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////// INSTALACION: EN UN PROYECTO CON WEBPACK ////////////////////////////////
/*
Si vas a usar React lo mas rapido es usar un boilerplate, osea un proyecto inicial con
todo configurado como este:
https://github.com/fermmm/boilerplate-typescript-react-redux-webpack
Para configurarlo de cero sin React estos son los pasos:
*/
/*
1) En el root del proyecto creamos un achivo llamado tsconfig.json con este contenido:
*/
{
"compileOnSave": false,
"compilerOptions": {
"noImplicitAny": true,
"allowJs": true,
"module": "ES6",
"target": "es5",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [ "es2015", "dom" ],
"moduleResolution": "node",
"sourceMap": true,
"suppressImplicitAnyIndexErrors": true,
"jsx": "react"
}
}
/*
2) En el archvo webpack.config.js dentro de module.rules tiene que estar esto:
*/
module: {
rules: [
...
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
/*
3) En el mismo archvo (webpack.config.js) dentro de resolve.extensions tiene que
estar '.tsx' y '.ts':
*/
resolve: {
extensions: [ '.tsx', '.ts', '.js' ]
},
/*
4) Ejecutar el siguiente comando:
npm install ts-loader typescript
*/
/*
Con eso ya tendría que funcionar Typescript.
*/