-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add Spanish translations for the playground #237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
//// { title: 'TypeScript con Deno', order: 3 } | ||
|
||
// Deno es un entorno en tiempo de ejecución aún | ||
// incompleto para JavaScript y TypeScript basado en | ||
// v8 con un enfoque marcado en la seguridad. | ||
|
||
// https://deno.land | ||
|
||
// Deno cuenta con un sistema de permisos con base en el aislamiento, | ||
// lo cual reduce el acceso que tiene JavaScript al sistema de | ||
// archivos o a la red y utiliza importaciones basadas en http, las | ||
// cuales son descargadas y almacenadas localmente. | ||
|
||
// Aquí hay un ejemplo del uso de deno para crear scripts: | ||
|
||
import compose from "https://deno.land/x/denofun/lib/compose.ts"; | ||
|
||
function greet(name: string) { | ||
return `¡Hola, ${name}!` | ||
} | ||
|
||
function makeLoud(x: string) { | ||
return x.toUpperCase(); | ||
} | ||
|
||
const greetLoudly = compose( | ||
makeLoud, | ||
greet | ||
); | ||
|
||
// Dice "¡HOLA, MUNDO!." | ||
greetLoudly("mundo"); | ||
|
||
import concat from "https://deno.land/x/denofun/lib/concat.ts"; | ||
|
||
// Devuelve "holamundo" | ||
concat("hola", "mundo"); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
//// { title: 'TypeScript con Node', order: 3, isJavaScript: true } | ||
|
||
// Node.js en un entorno de ejecución muy popular para JavaScript, | ||
// construido sobre v8, el motor de JavaScript que utiliza Chrome. | ||
// Puedes usarlo para construir servidores, interfaces de usuario y | ||
// cualquier otra cosa que se le parezca. | ||
|
||
// https://nodejs.org/ | ||
|
||
// Node.js tiene con un conjunto de bibliotecas principales que | ||
// extienden el entorno de ejecución de JavaScript. Van desde el | ||
// manejo de rutas del sistema operativo: | ||
|
||
import { join } from "path"; | ||
const myPath = join("~", "downloads", "todo_list.json"); | ||
|
||
// hasta la manipulación de archivos: | ||
|
||
import { readFileSync } from "fs"; | ||
const todoListText = readFileSync(myPath, "utf8"); | ||
|
||
// Puedes añadir incrementalmente tipos a tus proyectos de JavaScript | ||
// usando tipos al estilo JSDoc. Haremos uno de los elementos de | ||
// nuestra lista de tareas pendientes (en inglés TODOs) basados en | ||
// la estructura JSON: | ||
|
||
/** | ||
* @typedef {Object} TODO un elemento de TODO | ||
* @property {string} title El nombre a mostrar del elemento TODO | ||
* @property {string} body La descripción del elemento TODO | ||
* @property {boolean} done Si el elemento TODO ha sido o no completado | ||
*/ | ||
|
||
// Ahora asígnalo al valor de retorno de JSON.parse. | ||
// Para más información, dirígete a: example:jsdoc-support | ||
|
||
/** @type {TODO[]} una lista de TODOs */ | ||
const todoList = JSON.parse(todoListText); | ||
|
||
// Y manejo de procesos: | ||
import { spawnSync } from "child_process"; | ||
todoList | ||
.filter(todo => !todo.done) | ||
.forEach(todo => { | ||
// Usa el cliente ghi para crear una incidencia por cada | ||
// elemento de la lista que no se ha completado aún. | ||
|
||
// Observa que se activa correctamente el autocompletamiento | ||
// y la documentación en JS cuando señalas debajo a 'todo.title'. | ||
spawnSync(`ghi open --message "${todo.title}\n${todo.body}"`); | ||
}); | ||
|
||
// TypeScript tiene definiciones de tipos actualizadas para todos | ||
// los módulos incorporados por defecto, mediante DefinitelyTyped; | ||
carburo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// lo que significa que puedes escribir programas de node con una | ||
// sólida cobertura de tipos. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
//// { title: 'TypeScript con la Web', order: 0, isJavaScript: true } | ||
|
||
// El DOM (Document Object Model) es la API por detrás del | ||
// trabajo con una página web, y TypeScript tiene excelente | ||
// compatibilidad con esa API. | ||
carburo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Creemos un globo de ayuda (en inglés, popover) que se muestra cuando | ||
// se presiona "Ejecutar" en la barra de herramientas de arriba. | ||
|
||
const popover = document.createElement("div"); | ||
popover.id = "example-popover"; | ||
|
||
// Observa que el globo está correctamente anotado con el tipo | ||
// HTMLDivElement porque pasamos el elemento "div". | ||
|
||
// Para hacer posible volver a ejecutar este código, primero | ||
// añadiremos una función para eliminar el globo si ya existía. | ||
|
||
const removePopover = () => { | ||
const existingPopover = document.getElementById(popover.id); | ||
if (existingPopover && existingPopover.parentElement) { | ||
existingPopover.parentElement.removeChild(existingPopover); | ||
} | ||
}; | ||
|
||
// Y entonces llamarla inmediatamente. | ||
|
||
removePopover(); | ||
|
||
// Podemos establecer los estilos en línea del elemento a través | ||
// de la propiedad .style en un HTMLElement: tiene todos los tipos | ||
// definidos | ||
|
||
popover.style.backgroundColor = "#0078D4"; | ||
popover.style.color = "white"; | ||
popover.style.border = "1px solid black"; | ||
popover.style.position = "fixed"; | ||
popover.style.bottom = "10px"; | ||
popover.style.right = "20px"; | ||
popover.style.width = "200px"; | ||
popover.style.height = "100px"; | ||
popover.style.padding = "10px"; | ||
|
||
// Incluidos atributos CSS menos conocidos u obsoletos. | ||
popover.style.webkitBorderRadius = "4px"; | ||
|
||
// Para añadir contenido al globo, necesitaremos añadir | ||
// un elemento de párrafo y usarlo para añadir algún texto. | ||
|
||
const message = document.createElement("p"); | ||
message.textContent = "Here is an example popover"; | ||
|
||
// Y también añadiremos un botón de cerrar. | ||
|
||
const closeButton = document.createElement("a"); | ||
closeButton.textContent = "X"; | ||
closeButton.style.position = "absolute"; | ||
closeButton.style.top = "3px"; | ||
closeButton.style.right = "8px"; | ||
closeButton.style.color = "white"; | ||
|
||
closeButton.onclick = () => { | ||
removePopover() | ||
} | ||
|
||
// Y entonces añadir todos estos elementos a la página. | ||
popover.appendChild(message); | ||
popover.appendChild(closeButton); | ||
document.body.appendChild(popover); | ||
|
||
// Si ejecutas "Run" arriba, el popup debe aparecer | ||
// abajo a la izquierda, y lo puedes cerrar haciendo | ||
// click en la x en la parte superior derecha del popup. | ||
carburo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
// Este ejemplo muestra cómo puedes trabajar con la API | ||
// del DOM en JavaScript, pero usando TypeScript para | ||
// obtener mejores herramientas de asistencia. | ||
|
||
// Hay un ejemplo extendido para las herramientas de TypeScript | ||
// con WebGL disponible aquí: example:typescript-with-webgl |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
//// { title: 'Encadenamiento de funciones', order: 2, compiler: { esModuleInterop: true } } | ||
|
||
// Las APIs con funciones encadenadas son un patrón común en | ||
// JavaScript, lo que permite que tu código sea más conciso, | ||
// con menos valores intermedios y más fácil de leer debido | ||
// a sus habilidades de anidamiento. | ||
|
||
// Una API muy común que funciona con encadenamiento | ||
// es jQuery. Aquí hay un ejemplo de jQuery | ||
// usada con tipos de DefinitelyTyped: | ||
carburo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
import $ from "jquery"; | ||
|
||
// Aquí hay un ejemplo de uso de la API de jQuery: | ||
|
||
$("#navigation") | ||
.css("background", "red") | ||
.height(300) | ||
.fadeIn(200); | ||
|
||
// Si añades un punto en la línea de arriba, verás | ||
// una larga lista de funciones. Este patrón es fácil | ||
// de reproducir en JavaScript. La clave es asegurarse | ||
// de que siempre retornes el mismo objeto. | ||
|
||
// Aquí hay un ejemplo de API que crea una API con | ||
// encadenamiento. La clave es tener una función en | ||
// un nivel externo que mantenga información del estado | ||
// interno, y un objeto que exponga la API que se | ||
// devuelve siempre. | ||
|
||
const addTwoNumbers = (start = 1) => { | ||
let n = start; | ||
|
||
const api = { | ||
// Implement each function in your API | ||
add(inc: number = 1) { | ||
n += inc; | ||
return api; | ||
}, | ||
|
||
print() { | ||
console.log(n); | ||
return api; | ||
} | ||
}; | ||
return api; | ||
}; | ||
|
||
// Lo que permite el mismo estilo de API que | ||
// vimos en jQuery: | ||
|
||
addTwoNumbers(1) | ||
.add(3) | ||
.add() | ||
.print() | ||
.add(1); | ||
|
||
// Aquí hay un ejemplo similar que usa una clase: | ||
|
||
class AddNumbers { | ||
private n: number; | ||
|
||
constructor(start = 0) { | ||
this.n = start; | ||
} | ||
|
||
public add(inc = 1) { | ||
this.n = this.n + inc; | ||
return this; | ||
} | ||
|
||
public print() { | ||
console.log(this.n); | ||
return this; | ||
} | ||
} | ||
|
||
// Y aquí la vemos en acción: | ||
|
||
new AddNumbers(2) | ||
.add(3) | ||
.add() | ||
.print() | ||
.add(1); | ||
|
||
// Este ejemplo hace uso de la inferencia | ||
// de tipos de TypeScript como una forma | ||
// de proporcionar herramientas para patrones | ||
// de JavaScript. | ||
|
||
// Para más ejemplos sobre esto: | ||
// | ||
// - example:code-flow |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
//// { title: 'Funciones genéricas' } | ||
|
||
// La genericidad proporciona una forma de utilizar tipos | ||
// como variables en otros tipos. Meta. | ||
Comment on lines
+3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Also, what is Meta on the original file? Maybe some extra word or was on purpose? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sí, está en el original. Se refiere a la primera oración de que la genericidad permite usar tipos como variables en otros tipos (algo así como metatipos). No estoy seguro cuál sería la forma más idiomática de traducirlo. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, utiliza There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤔 No creo que metadatos sea exactamente la traducción más feliz. En el texto original parece más bien una forma de guiño o broma al lector. |
||
|
||
// Intentaremos mantener este ejemplo simple. Puedes hacer | ||
// muchas cosas con la genericidad y probablemente verás | ||
// en algún punto código muy complicado usando genericidad. | ||
// Pero eso no significa que la genericidad es complicada. | ||
|
||
// Comenzaremos con un ejemplo donde envolvemos un objeto de | ||
// entrada en un arreglo. Solo nos importará una variable en | ||
// este caso, el tipo suministrado: | ||
|
||
function wrapInArray<Type>(input: Type): Type[] { | ||
return [input]; | ||
} | ||
|
||
// Nota: es común ver el tipo Type como T. Esto es culturalmente | ||
// similar a como las personas usan i en un cliclo for para | ||
// representar index. T normalmente representa Type, por lo | ||
// que usaremos el nombre completo para mayor claridad. | ||
|
||
// Nuestra función usará inferencia para siempre mantener | ||
// el tipo suministrado como entrada igual al suministrado | ||
// como salida (aunque será envuelto en un arreglo). | ||
|
||
const stringArray = wrapInArray("hello generics"); | ||
const numberArray = wrapInArray(123); | ||
|
||
// Podemos verificar que funciona como se espera comprobando | ||
// si podemos asignar un arreglo de cadenas a una función | ||
// que debe ser un arreglo de objetos. | ||
const notStringArray: string[] = wrapInArray({}); | ||
|
||
// Además puedes saltarte la inferencia de tipos si añades | ||
// el tipo tú mismo: | ||
const stringArray2 = wrapInArray<string>(""); | ||
|
||
// wrapInArray permite que se use cualquier tipo, sin embargo | ||
carburo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// hay casos en que necesitas permitir solo un subconjunto de | ||
// tipos. En estos casos puedes decir que el tipo tiene que | ||
// extender un tipo en particular. | ||
|
||
interface Drawable { | ||
draw: () => void; | ||
} | ||
|
||
// Esta función toma un conjunto de objetos que tiene una función | ||
// para dibujar en la pantalla | ||
function renderToScreen<Type extends Drawable>(input: Type[]) { | ||
input.forEach(i => i.draw()); | ||
} | ||
|
||
const objectsWithDraw = [{ draw: () => { } }, { draw: () => { } }]; | ||
renderToScreen(objectsWithDraw); | ||
|
||
// Fallará si falta draw: | ||
carburo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
renderToScreen([{}, { draw: () => {} }]); | ||
|
||
// La genericidad puede comenzar a parecer complicada cuando tienes | ||
// múltiples variables. Aquí hay un ejemplo de una función de caché | ||
// que te permite tener diferentes conjuntos de tipos de entrada y | ||
// de cachés. | ||
|
||
interface CacheHost { | ||
save: (a: any) => void; | ||
} | ||
|
||
function addObjectToCache<Type, Cache extends CacheHost>(obj: Type, cache: Cache): Cache { | ||
cache.save(obj); | ||
return cache; | ||
} | ||
|
||
// Esto es lo mismo que lo anterior, pero con un parámetro extra. | ||
// Nota: Sin embargo para que esto funcione debimos usar any. | ||
carburo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
// Esto puede solucionarse usando una interfaz genérica. | ||
|
||
interface CacheHostGeneric<ContentType> { | ||
save: (a: ContentType) => void; | ||
} | ||
|
||
// Ahora cuando se usa CacheHostGeneric, necesitas decirle | ||
// qué ContentType es. | ||
|
||
function addTypedObjectToCache<Type, Cache extends CacheHostGeneric<Type>>(obj: Type, cache: Cache): Cache { | ||
cache.save(obj); | ||
return cache; | ||
} | ||
|
||
// Eso escaló bastante rápido en términos de sintaxis. Sin | ||
// embargo provee más seguridad. Estas son decisiones que | ||
// ahora tienes más conocimiento para hacer. Al proporcionar | ||
// APIs para terceros, la genericidad ofrece una forma flexible | ||
// de permitir a otros utilizar sus propios tipos con total capacidad | ||
// de inferencia de código. | ||
|
||
// Para más ejemplos de genericidad con clases e interfaces: | ||
// | ||
// example:advanced-classes | ||
// example:typescript-with-react | ||
// https://www.typescriptlang.org/docs/handbook/generics.html |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No veo motivo para añadir información adicional a la que está en documento original:
Allí nunca se menciona a Google.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Siempre es bueno clarificar de donde proviene el motor. No creo que exista problema con ello, además que ayuda a los nuevos desarrolladores a indagar en el tema.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
De acuerdo en ese aspecto, pero la cuestión es hasta dónde llega el punto del traductor. Mi punto es que no estamos generando contenido original. Creo que en este caso lo mejor es proponer el cambio en la versión en inglés que sirve como referencia y a partir de ahí todas las traducciones se pueden beneficiar.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Podemos dejarlo en tu versión por ahora para no retrasar lo demás y preguntar en el discord 👍