diff --git a/packages/playground-examples/copy/es/TypeScript/Primitives/Any.ts b/packages/playground-examples/copy/es/TypeScript/Primitives/Any.ts new file mode 100644 index 000000000000..19a9dc3bb35c --- /dev/null +++ b/packages/playground-examples/copy/es/TypeScript/Primitives/Any.ts @@ -0,0 +1,53 @@ +// Any es la via de escape de TypeScript. Puedes usar any +// para declarar que una sección de tu código es dinámica y +// parecida a JavaScript, o como solución alternativa para +// las limitaciones del sistema de tipado. + +// Un buen caso de uso de any es el análisis del formato JSON: + +const myObject = JSON.parse("{}"); + +// Any le hace saber a TypeScript que confíe en su código +// como seguro porque conoce más sobre este, incluso si +// eso no es estrictamente cierto. Por ejemplo, este código +// no funcionará: + +myObject.x.y.z; + +// Haciendo uso de any le permite tener la habilidad de escribir +// código similar al JavaScript original sacrificando el sistema +// de tipado. + +// Se puede decir que any es un `tipo comodín`, el cual permite +// ser reemplazado con cualquier otro tipo (exceptuando never) +// con el fin de asignar tipos diferentes entre si. + +declare function debug(value: any): void; + +debug("a string"); +debug(23); +debug({ color: "blue" }); + +// Cada llamado de depuración esta permitido ya que puedes +// reemplazar any con el tipo del argumento a coincidir. + +// TypeScript tendrá en cuenta la posición de los anys en +// diferentes formas, por ejemplo con estas tuplas para el +// argumento de la función. + +declare function swap(x: [number, string]): [string, number]; + +declare const pair: [any, any]; +swap(pair); + +// El llamado a la función swap es permitido porque el +// argumento puede ser emparejado reemplazando el primer `any` +// en el par con el tipo number, y el segundo `any` con el +// tipo string. + +// Si las tuplas son algo nuevo para ti, veasé: example:tuples + +// Unknown es un tipo hermano de `any`, siendo `any` para +// decir "Sé lo que es mejor", mientras que `unknown` es una forma +// de decir "No estoy seguro de lo que es mejor, así que tienes +// que decirle a TS el tipo" example:unknown-and-never diff --git a/packages/playground-examples/copy/es/TypeScript/Primitives/Literals.ts b/packages/playground-examples/copy/es/TypeScript/Primitives/Literals.ts new file mode 100644 index 000000000000..89999df66cdd --- /dev/null +++ b/packages/playground-examples/copy/es/TypeScript/Primitives/Literals.ts @@ -0,0 +1,68 @@ +//// { title: 'Literales' } + +// TypeScript tambien cuenta con algunos casos especiales +// para los literales en el código fuente. + +// De hecho, gran parte del soporte está cubierto por la expansión +// y redución de tipos ( example:type-widening-narrowing ) y vale +// la pena hablar de ello primero. + +// Un literal es un subtipo más concreto de un tipo común. +// Lo que esto significa es que "Hello World" es una cadena, +// pero una cadena no es "Hello World" dentro del sistema de tipos. + +const helloWorld = "Hello World"; +let hiWorld = "Hi World"; // esto es una cadena porque se define con let + +// Esta función acepta todas las cadenas +declare function allowsAnyString(arg: string); +allowsAnyString(helloWorld); +allowsAnyString(hiWorld); + +// Esta función solo acepta la cadena literal "Hello World" +declare function allowsOnlyHello(arg: "Hello World"); +allowsOnlyHello(helloWorld); +allowsOnlyHello(hiWorld); + +// Esto te permite declarar APIs que usan uniones para decir +// que solo acepta unos literales en particular. + +declare function allowsFirstFiveNumbers(arg: 1 | 2 | 3 | 4 | 5); +allowsFirstFiveNumbers(1); +allowsFirstFiveNumbers(10); + +let potentiallyAnyNumber = 3; +allowsFirstFiveNumbers(potentiallyAnyNumber); + +// A primera vista, esta regla no se aplica a los objetos complejos. + +const myUser = { + name: "Sabrina", +}; + +// Notesé como transforma `name: "Sabrina"` a `name: string` +// aún cuando está definida como una constante. Esto se debe +// a que el nombre todavía puede cambiar en cualquier momento: + +myUser.name = "Cynthia"; + +// Debido a que la propiedad `name` de `myUser` puede cambiar, +// TypeScript no puede usar la versión literal en el sistema +// de tipos. Sin embargo, hay una característica que le permitirá +// hacer esto. + +const myUnchangingUser = { + name: "Fatma", +} as const; + +// Cuando se aplica "as const" al objeto, entonces se convierte +// en un objeto literal que no cambia a diferencia de un objeto +// mutable que sí puede. + +myUnchangingUser.name = "Raîssa"; + +// "as const" es una gran herramienta para datos fijos, y lugares +// donde se trata el código como literales en línea. "as const" +// también funciona con los arreglos: + +const exampleUsers = [{ name: "Brian" }, { name: "Fahrooq" }] as const; diff --git a/packages/playground-examples/copy/es/TypeScript/Primitives/Union and Intersection Types.ts b/packages/playground-examples/copy/es/TypeScript/Primitives/Union and Intersection Types.ts new file mode 100644 index 000000000000..3dfbe2135ae5 --- /dev/null +++ b/packages/playground-examples/copy/es/TypeScript/Primitives/Union and Intersection Types.ts @@ -0,0 +1,86 @@ +//// { title: 'Tipos Unión e Intersección' } + +// Las uniones de tipo son una forma de declarar que un +// objeto podría ser de más de un tipo. + +type StringOrNumber = string | number; +type ProcessStates = "open" | "closed"; +type OddNumbersUnderTen = 1 | 3 | 5 | 7 | 9; +type AMessyUnion = "hello" | 156 | { error: true }; + +// Si el uso de "open" y "closed" frente a una cadena es +// nuevo para ti, miresé: example:literals + +// Podemos mezclar diferentes tipos en una unión, y con ello +// decir que el valor es uno de esos tipos. + +// TypeScript te dejará entonces averiguar cómo determinar +// qué valor podría ser en tiempo de ejecución. + +// Las uniones pueden a veces ser socavadas por el +// ensanchamiento del tipo, por ejemplo: + +type WindowStates = "open" | "closed" | "minimized" | string; + +// Si inspecciona arriba, podrá ver que WindowStates +// se convierte en una cadena - no en la unión. Esto es +// explicado en example:type-widening-and-narrowing + +// Si una unión es una operación OR, entonces una intersección +// es una operación AND. Las intersecciones de tipo son cuando +// dos tipos se cruzan para crear un nuevo tipo. Esto permite +// la composición del tipo. + +interface ErrorHandling { + success: boolean; + error?: { message: string }; +} + +interface ArtworksData { + artworks: { title: string }[]; +} + +interface ArtistsData { + artists: { name: string }[]; +} + +// Estas interfaces pueden estar compuestas por respuestas +// que tienen tanto un manejo consistente de errores como +// sus propios datos. + +type ArtworksResponse = ArtworksData & ErrorHandling; +type ArtistsResponse = ArtistsData & ErrorHandling; + +// Por ejemplo: + +const handleArtistsResponse = (response: ArtistsResponse) => { + if (response.error) { + console.error(response.error.message); + return; + } + + console.log(response.artists); +}; + +// Una mezcla de tipos de Intersección y Unión se vuelve +// realmente útil cuando tienes casos en los que un objeto +// tiene que incluir uno de dos valores: + +interface CreateArtistBioBase { + artistID: string; + thirdParty?: boolean; +} + +type CreateArtistBioRequest = (CreateArtistBioBase & { html: string }) | { markdown: string }; + +// Ahora sólo puedes crear una petición cuando incluyes +// artistID y los campos html o markdown + +const workingRequest: CreateArtistBioRequest = { + artistID: "banksy", + markdown: "Banksy is an anonymous England-based graffiti artist...", +}; + +const badRequest: CreateArtistBioRequest = { + artistID: "banksy", +}; diff --git a/packages/playground-examples/copy/es/TypeScript/Primitives/Unknown and Never.ts b/packages/playground-examples/copy/es/TypeScript/Primitives/Unknown and Never.ts new file mode 100644 index 000000000000..18c8ae5916a4 --- /dev/null +++ b/packages/playground-examples/copy/es/TypeScript/Primitives/Unknown and Never.ts @@ -0,0 +1,134 @@ +//// { title: 'Unknown y Never' } + +// Unknown + +// Unknown es uno de esos tipos que una vez que lo usas, puedes encontrar +// bastantes usos para él. Actúa como un hermano para el tipo `any`. +// Donde `any` permite la ambigüedad, `unknown` requiere de detalles. + +// Un buen ejemplo sería envolver un analizador JSON. +// Los datos JSON pueden venir en muchas formas diferentes +// y el creador de la función de análisis JSON no sabrá la +// forma de los datos - la persona que llama a esa función debería. + +const jsonParser = (jsonString: string) => JSON.parse(jsonString); + +const myAccount = jsonParser(`{ "name": "Dorothea" }`); + +myAccount.name; +myAccount.email; + +// Si inspecciona jsonParser, puedes ver que retorna el tipo `any`, +// por lo que myAccount también. Es posible arreglar esto con los +// genéricos, pero también es posible arreglar esto con los desconocidos. + +const jsonParserUnknown = (jsonString: string): unknown => JSON.parse(jsonString); + +const myOtherAccount = jsonParserUnknown(`{ "name": "Samuel" }`); + +myOtherAccount.name; + +// El objeto myOtherAccount no puede ser usado hasta que el tipo +// haya sido declarado en TypeScript. Esto puede ser utilizado +// para asegurarse que los consumidores de la API piensen en +// su tipo por adelantado: + +type User = { name: string }; +const myUserAccount = jsonParserUnknown(`{ "name": "Samuel" }`) as User; +myUserAccount.name; + +// Unknown es una gran herramienta, para entender más sobre ello: +// https://mariusschulz.com/blog/the-unknown-type-in-typescript +// https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#new-unknown-top-type + +// Never + +// Debido a que TypeScript soporta el análisis del flujo de código, +// el lenguaje debe ser capaz de representar cuando el código +// lógicamente no puede suceder. Por ejemplo, esta función no puede +// retornar: + +const neverReturns = () => { + // Arroja en la primera linea + throw new Error("Always throws, never returns"); +}; + +// Si inspecciona el tipo, puedes ver que es () => never +// el cual significa que esto no puede suceder. Estos todavía +// pueden ser utilizados como otros valores: + +const myValue = neverReturns(); + +// El hecho de que una función retorne `never` puede ser útil +// cuando se trata de la imprevisibilidad del entorno de ejecución +// de JavaScript y de los consumidores de APIs que podrían no +// estar utilizando tipos: + +const validateUser = (user: User) => { + if (user) { + return user.name !== "NaN"; + } + + // De acuerdo al sistema de tipado, este código nunca puede + // ocurrir, el cual encaja con el tipo retornado de neverReturns + + return neverReturns(); +}; + +// La definición de tipos declara que un usuario tiene que ser +// suministrado pero existen suficientes mecanismos de escape +// en JavaScript donde no puedes garantizar eso. + +// Utilizar una función que retorna `never` permite agregar +// código adicional en lugares donde no debería ser posible. +// Esto es muy útil para presentar mejores mensajes de error +// o para cerrar recursos como archivos o ciclos. + +// Un uso popular para `never` es asegurarse de que una +// cláusula `switch` sea exhaustiva. Por ejemplo, que todas +// las rutas han sido cubiertas. + +// Aquí hay una enumeración y una cláusula `switch` exhaustiva, +// intenta añadir una nueva opción a la enumeración +// (¿tal vez Tulip?) + +enum Flower { + Rose, + Rhododendron, + Violet, + Daisy, +} + +const flowerLatinName = (flower: Flower) => { + switch (flower) { + case Flower.Rose: + return "Rosa rubiginosa"; + case Flower.Rhododendron: + return "Rhododendron ferrugineum"; + case Flower.Violet: + return "Viola reichenbachiana"; + case Flower.Daisy: + return "Bellis perennis"; + + default: + const _exhaustiveCheck: never = flower; + return _exhaustiveCheck; + } +}; + +// Recibirás un error de compilación diciendo que tu +// nuevo tipo de flor no puede convertirse en `never`. + +// Never en Uniones + +// Un tipo `never` es algo que es automáticamente removido +// de una unión de tipos. + +type NeverIsRemoved = string | never | number; + +// Si analizas el tipo de NeverIsRemoved, podrás observar que +// es un string | number. Esto se debe a nunca puede pasar en +// tiempo de ejecución debido a que no puedes asignar a un tipo +// `never`. + +// Esta característica es bastante utilizada en example:conditional-types