{"id":13456692,"url":"https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es","last_synced_at":"2025-10-15T12:32:42.655Z","repository":{"id":45505148,"uuid":"224607190","full_name":"typescript-cheatsheets/react-typescript-cheatsheet-es","owner":"typescript-cheatsheets","description":"Cheatsheets para desarrolladores expertos en React que comienzan con TypeScript","archived":false,"fork":false,"pushed_at":"2022-04-30T23:07:36.000Z","size":211,"stargazers_count":209,"open_issues_count":1,"forks_count":38,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-07-09T14:37:01.137Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://twitter.com/laurosilvacom/status/1205700402231963649","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/typescript-cheatsheets.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-28T08:38:16.000Z","updated_at":"2025-06-18T21:45:07.000Z","dependencies_parsed_at":"2022-07-15T08:51:34.814Z","dependency_job_id":null,"html_url":"https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/typescript-cheatsheets/react-typescript-cheatsheet-es","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typescript-cheatsheets%2Freact-typescript-cheatsheet-es","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typescript-cheatsheets%2Freact-typescript-cheatsheet-es/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typescript-cheatsheets%2Freact-typescript-cheatsheet-es/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typescript-cheatsheets%2Freact-typescript-cheatsheet-es/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/typescript-cheatsheets","download_url":"https://codeload.github.com/typescript-cheatsheets/react-typescript-cheatsheet-es/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/typescript-cheatsheets%2Freact-typescript-cheatsheet-es/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265229772,"owners_count":23731255,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T08:01:26.120Z","updated_at":"2025-10-15T12:32:37.617Z","avatar_url":"https://github.com/typescript-cheatsheets.png","language":null,"funding_links":[],"categories":["miscellaneous"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003ch1\u003eReact+TypeScript Cheatsheets en Español\u003c/h1\u003e\n\n\u003ca href=\"https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/81\"\u003e\n  \u003cimg\n    height=\"90\"\n    width=\"90\"\n    alt=\"react + ts logo\"\n    src=\"https://user-images.githubusercontent.com/6764957/53868378-2b51fc80-3fb3-11e9-9cee-0277efe8a927.png\"\n    align=\"left\"\n  /\u003e\n\u003c/a\u003e\n\n\u003cp\u003eCheatsheets para desarrolladores expertos en React que comienzan con TypeScript\u003c/p\u003e\n\n[**Básico**](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es#tabla-de-contenidos-de-la-cheatsheet-básica) |\n[**Avanzado**](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es/blob/master/AVANZADO.md) |\n[**Migrando**](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es/blob/master/MIGRANDO.md) |\n[**HOC**](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es/blob/master/HOC.md) |\n[**Inglés**](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet) |\n[**中文翻译**](https://github.com/fi3ework/blog/tree/master/react-typescript-cheatsheet-cn) |\n[Contribuir](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es/blob/master/CONTRIBUYENDO.md) |\n[Preguntas](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es/issues/new)\n\n---\n\n:wave: Este repositorio es mantenido por [@laurosilvacom](https://twitter.com/laurosilvacom), [@aromanarguello](https://twitter.com/aromanarguello), [@rainerxmf ](https://twitter.com/rainerxmf), [@dantehemerson](https://twitter.com/dantehemerson), y [@hanslgarcia](https://twitter.com/HansLGarcia) . ¡Estamos tan contentos de que quieras probar TypeScript con React! Si ves que algo esta mal, ¡abre un [_Issue_](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet-es/issues/new)! :+1:\n\n---\n\n\u003c/div\u003e\n\n[![All Contributors](https://img.shields.io/github/contributors/typescript-cheatsheets/react-typescript-cheatsheet?color=orange\u0026style=flat-square)](/COLABORADORES.md)\n\n## All React + TypeScript Cheatsheets\n\n- **La cheatsheet básica** ([`/README.md`](/README.md#basic-cheatsheet-table-of-contents)) se enfoca en ayudar a los desarrolladores de React a comenzar a usar TS en **aplicaciones** de React\n  - Enfoque en buenas prácticas (según nuestra opinión) y ejemplos que se puedan copiar y pegar.\n  - Explica en la marcha el uso y configuración de algunos tipos básicos de TS.\n  - Responde las preguntas más frecuentes.\n  - El objetivo es lograr volverse efectivo con TS sin aprender _demasiado_ TS.\n- **La cheatsheet avanzada** ([`/AVANZADO.md`](/AVANZADO.md)) ayuda a mostar y explicar usos avanzados de los tipos genéricos para personas que escriben tipos reutilizables en utilidades/funciones/render props/components de orden superior y **bibliotecas** de TS+React.\n  - También tiene consejos y trucos variados para usuarios avanzados.\n  - Consejos para contribuir a DefinitelyTyped\n  - El objetivo es _aprovechar al máximo_ TypeScript.\n- **La cheatsheet de migración** ([`/MIGRATING.md`](/MIGRATING.md)) ayuda a agrupar consejos para migrar incrementalmente una base de código grande de JS o Flow, **de personas que lo han hecho**.\n  - No intentamos convencer a las personas a hacer el cambio, solo ayudar a aquellos que ya se han decidido.\n  - ⚠️Esta es una nueva cheatsheet, toda ayuda es bienvenida.\n- **La cheatsheet HOC** ([`/HOC.md`](/HOC.md)) enseña específicamente a las personas a escribir componentes de orden superior (HOC por sus siglas en inglés) con ejemplos.\n  - Es necesario estar familiarizado con la [Genericidad](https://www.typescriptlang.org/docs/handbook/generics.html).\n  - ⚠️Esta es una nueva cheatsheet, toda ayuda es bienvenida.\n\n---\n\n### Tabla de contenidos de la Cheatsheet básica\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003cb\u003eExpandir tabla de contenidos\u003c/b\u003e\u003c/summary\u003e\n\n- [Sección 1: Configuración](#sección-1-configuración)\n  - [Prerrequisitos](#prerrequisitos)\n  - [Herramientas de inicio de React + TypeScript](#herramientas-de-inicio-de-react--typescript)\n  - [Importar React](#importar-react)\n- [Sección 2: Comienzo](#sección-2-comienzo)\n  - [Componentes de función](#componentes-de-función)\n  - [Hooks](#hooks)\n  - [Componentes de clase](#componentes-de-clase)\n  - [Tipos de defaultProps](#tipos-de-defaultprops)\n  - [¿Tipos o interfaces?](#tipos-o-interfaces)\n  - [Ejemplos básicos de Prop Types](#ejemplos-básicos-de-prop-types)\n  - [Ejemplos útiles de tipos de props en React](#ejemplos-útiles-de-tipos-de-props-en-react)\n  - [getDerivedStateFromProps](#getderivedstatefromprops)\n  - [Formularios y Eventos](#formularios-y-eventos)\n  - [Contexto](#contexto)\n  - [forwardRef/createRef](#forwardrefcreateref)\n  - [Portales](#portales)\n  - [Barreras de error](#barreras-de-error)\n  - [Concurrent React/React Suspense](#concurrent-reactreact-suspense)\n- [Manual básico de resolución de problemas: Tipos](#manual-básico-de-resolución-de-problemas-tipos)\n  - [Tipos de unión y seguro de tipo](#tipos-de-unión-y-seguro-de-tipo)\n  - [Tipos opcionales](#tipos-opcionales)\n  - [Tipos Enum](#tipos-enum)\n  - [Aserción de tipo](#aserción-de-tipo)\n  - [Simulación de tipos nominales](#simulación-de-tipos-nominales)\n  - [Tipos de intersección](#tipos-de-intersección)\n  - [Tipos de unión](#tipos-de-unión)\n  - [Sobrecarga de tipos de función](#sobrecarga-de-tipos-de-función)\n  - [Uso de tipos inferidos](#uso-de-tipos-inferidos)\n  - [Uso de tipos parciales](#uso-de-tipos-parciales)\n  - [¡Los tipos que necesito no fueron exportados!](#los-tipos-que-necesito-no-fueron-exportados)\n- [Manual de resolución de problemas: Imágenes y otros archivos que no son TS/TSX](#manual-de-resolución-de-problemas-imágenes-y-otros-archivos-que-no-son-tstsx)\n- [Manual de resolución de problemas: Operadores](#manual-de-resolución-de-problemas-operadores)\n- [Manual de resolución de problemas: Utilitarios](#manual-de-resolución-de-problemas-utilitarios)\n- [Manual de resolución de problemas: ESLint](#manual-de-resolución-de-problemas-eslint)\n- [Manual de resolución de problemas: tsconfig.json](#manual-de-resolución-de-problemas-tsconfigjson)\n- [Manual de resolución de problemas: Errores en tipos oficiales](#manual-de-resolución-de-problemas-errores-en-tipos-oficiales)\n- [Bases de código de React + TypeScript recomendadas para aprender](#bases-de-código-de-react--typescript-recomendadas-para-aprender)\n- [Herramientas e integración en editores](#herramientas-e-integración-en-editores)\n- [Linting](#linting)\n- [Otros recursos sobre React + TypeScript](#otros-recursos-sobre-react--typescript)\n- [Charlas recomendadas sobre React + TypeScript](#charlas-recomendadas-sobre-react--typescript)\n- [Hora de realmente aprender TypeScript](#hora-de-realmente-aprender-typescript)\n- [Aplicación de ejemplo](#aplicación-de-ejemplo)\n- [¡Mi pregunta no está respondida aquí!](#mi-pregunta-no-está-respondida-aquí)\n  - [Contribuidores](#contribuidores)\n\n\u003c/details\u003e\n\n# Sección 1: Configuración\n\n## Prerrequisitos\n\n1. Buena comprensión de [React](https://reactjs.org)\n2. Estar familiarizado con con los [tipos de TypeScript básicos](https://www.typescriptlang.org/docs/handbook/basic-types.html) ([La guía de 2ality](http://2ality.com/2018/04/type-notation-typescript.html) es de ayuda)\n3. Haber leído la [sección sobre TypeScript en la documentación oficial de React](https://es.reactjs.org/docs/static-type-checking.html#typescript).\n4. Haber leído [la sección de React del nuevo Typescript playground](http://www.typescriptlang.org/play/index.html?jsx=2\u0026esModuleInterop=true\u0026e=181#example/typescript-with-react) (opcional: además haga los 40+ ejemplos debajo de la sección de ejemplos [del playground](http://www.typescriptlang.org/play/index.html))\n\nEsta guía siempre asumirá que estás iniciando con la última versión de Typescript. Las notas para versiones anteriores se encontrarán en etiquetas expandibles `\u003cdetails\u003e`.\n\n## Herramientas de inicio de React + TypeScript\n\n1. [Create React App v2.1+ con Typescript](https://facebook.github.io/create-react-app/docs/adding-typescript): `npx create-react-app my-app --template typescript`\n\n- Solíamos recomendar `create-react-app-typescript` pero ahora está [desaconsejado](https://www.reddit.com/r/reactjs/comments/a5919a/createreactapptypescript_has_been_archived_rip/). [consulta las instrucciones para la migración](https://vincenttunru.com/migrate-create-react-app-typescript-to-create-react-app/)\n\n2. [La guía de Basarat](https://github.com/basarat/typescript-react/tree/master/01%20bootstrap) para una **configuración manual** de React + TypeScript + Webpack + Babel\n\n- En particular, asegúrate de tener `@types/react` y `@types/react-dom` instalados ([Lee más acerca del proyecto DefinitelyTyped si no estás familiarizado](https://definitelytyped.org/)).\n- También hay muchos _boilerplates_ de React + Typescript, por favor consulta [nuestra lista de recursos debajo](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet#recommended-react--typescript-codebases-to-learn-from).\n\n## Importar React\n\n```tsx\nimport * as React from \"react\";\nimport * as ReactDOM from \"react-dom\";\n```\n\nEn [TypeScript 2.7+](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html), puedes correr TypeScript con `--allowSyntheticDefaultImports` (o añadir `\"allowSyntheticDefaultImports\": true` a tsconfig) para importar como se hace normalmente en jsx:\n\n```tsx\nimport React from \"react\";\nimport ReactDOM from \"react-dom\";\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExplicación\u003c/summary\u003e\n\n¿Por qué `allowSyntheticDefaultImports` sobre `esModuleInterop`? [Daniel Rosenwasser](https://twitter.com/drosenwasser/status/1003097042653073408) ha dicho que es mejor para webpack/parcel. Para consultar más argumentos en el debate visita \u003chttps://github.com/wmonk/create-react-app-typescript/issues/214\u003e\n\n¡Por favor haz un PR o [abre un _issue_](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new) con tus sugerencias!\n\n\u003c/details\u003e\n\n# Sección 2: Comienzo\n\n## Componentes de función\n\nPueden escribirse como funciones normales que pueden tomar un argumento `props` y retornar un elemento JSX.\n\n```tsx\ntype AppProps = { message: string }; /* también se puede usar una interfaz */\nconst App = ({ message }: AppProps) =\u003e \u003cdiv\u003e{message}\u003c/div\u003e;\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003cb\u003e¿Y dónde queda `React.FC`/`React.FunctionComponent`?\u003c/b\u003e\u003c/summary\u003e\n\nTambién puedes escribir componentes con `React.FunctionComponent` (o la forma abreviada `React.FC`):\n\n```tsx\nconst App: React.FC\u003c{ message: string }\u003e = ({ message }) =\u003e (\n  \u003cdiv\u003e{message}\u003c/div\u003e\n);\n```\n\nAlgunas diferencias con la versión \"normal de función\":\n\n- Proporciona chequeo de tipos y autocompletamiento para propiedades estáticas como `displayName`, `propTypes`, y `defaultProps` - **Sin embargo**, actualmente existen problemas conocidos cuando se usa `defaultProps` con `React.FunctionComponent`. Consulta [este _issue_ para los detalles](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/87) (navega hacia nuestra sección sobre `defaultProps` para las recomendaciones sobre la declaración de tipos).\n\n- Proporciona una definición implícita de `children` (ver debajo); sin embargo existen algunos problemas con el tipo implícito `children` (p.ej. [DefinitelyTyped#33006](https://github.com/DefinitelyTyped/DefinitelyTyped/issues/33006)), y podría considerarse de todas formas ser explícito en los componentes que consumen `children`.\n\n```tsx\nconst Title: React.FunctionComponent\u003c{ title: string }\u003e = ({\n  children,\n  title\n}) =\u003e \u003cdiv title={title}\u003e{children}\u003c/div\u003e;\n```\n\n- _En el futuro_, podría marcar props automáticamente como `readonly`, aunque es discutible si el objeto props se desestructura en la lista de parámetros.\n\n- `React.FunctionComponent` es explícito sobre el tipo de retorno, mientras la forma normal de función es implícita (o de lo contrario necesita anotaciones adicionales).\n\nEn la mayoría de los casos no importa mucho qué sintaxis se use, pero la sintaxis de `React.FC` es ligeramente más verbosa sin proporcionar una clara ventaja, por lo que se le da precedencia a la sintaxis \"normal de función\".\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eProblemas menores\u003c/b\u003e\u003c/summary\u003e\n\nEstos patrones no se permiten:\n\n**Renderizado condicional**\n\n```tsx\nconst MyConditionalComponent = ({ shouldRender = false }) =\u003e\n  shouldRender ? \u003cdiv /\u003e : false; // no hagas esto tampoco en JS\nconst el = \u003cMyConditionalComponent /\u003e; // lanza un error\n```\n\nEsto ocurre por limitaciones en el compilador, los componentes de función no pueden retornar otra cosa que no sea una expresión JSX o `null`, de lo contrario se queja con un mensaje de error críptico qeu dice que el otro tipo no es asignable a `Element`.\n\n```tsx\nconst MyArrayComponent = () =\u003e Array(5).fill(\u003cdiv /\u003e);\nconst el2 = \u003cMyArrayComponent /\u003e; // lanza un error\n```\n\n**Array.fill**\n\nDesafortunadamente con simplemente anotar el tipo de la función no se resolverá, por lo que si realmente necesitas retornar otros tipos exóticos con los que React es compatible, necesitarás realizar una aserción de tipo:\n\n```tsx\nconst MyArrayComponent = () =\u003e (Array(5).fill(\u003cdiv /\u003e) as any) as JSX.Element;\n```\n\n[Consulta aquí el comentario de @ferdaber](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/57).\n\n\u003c/details\u003e\n\n## Hooks\n\nLos Hooks están incluidos [en `@types/react` desde la versión v16.8 en adelante](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a05cc538a42243c632f054e42eab483ebf1560ab/types/react/index.d.ts#L800-L1031).\n\n**useState**\n\nLa inferencia de tipo funciona muy bien la mayoría de las veces:\n\n```tsx\nconst [val, toggle] = React.useState(false); // se infiere que `val` es un booleao, `toggle` solo toma booleanos\n```\n\nConsulta también la sección sobre el [Uso de tipos inferidos](#using-inferred-types) si necesitas usar un tipo complejo y te has apoyado en la inferencia para hacerlo.\n\nSin embargo, muchos hooks son inicializados con valores por defecto de tipo null o semejantes y puede que te preguntes como proporcionar tipos. Declara explícitamente el tipo y utiliza un tipo de unión:\n\n```tsx\nconst [user, setUser] = React.useState\u003cIUser | null\u003e(null);\n\n// later...\nsetUser(newUser);\n```\n\n**useRef**\n\nCuando utilices `useRef`, tienes dos opciones al crear un contenedor de la ref que no tiene un valor inicial:\n\n```ts\nconst ref1 = useRef\u003cHTMLElement\u003e(null!);\nconst ref2 = useRef\u003cHTMLElement | null\u003e(null);\n```\n\nLa primera opción hará que `ref1.current` sea de solo lectura y se usa para pasarla a los atributos incorporados `ref` que React manejará (porque React maneja la actualización del valor `current` por ti).\n\nLa segunda opción hará que `ref2.current` sea mutable, y se usa para \"variables de instancia\" que quieres manejar tú mismo.\n\n**useEffect**\n\nAl utilizar `useEffect`, asegúrate de no retornar otra cosa que no sea una función o `undefined`, de otra forma tanto TypeScript como React se quejarán. Esto puede ser sútil al usar funciones flecha:\n\n```ts\nfunction DelayedEffect(props: { timerMs: number }) {\n  const { timerMs } = props;\n  // mal! setTimeout retorna implícitamente un número porque la función flecha no está envuelta en llaves\n  useEffect(\n    () =\u003e\n      setTimeout(() =\u003e {\n        /* do stuff */\n      }, timerMs),\n    [timerMs]\n  );\n  return null;\n}\n```\n\n**useRef**\n\n```tsx\nfunction TextInputWithFocusButton() {\n  // inicializa con null, pero dile a TypeScript que estamos buscando un HTMLInputElement\n  const inputEl = React.useRef\u003cHTMLInputElement\u003e(null);\n  const onButtonClick = () =\u003e {\n    // Los chequeos estrictos de null requieren que verifiquemos si inputEl y current existen.\n    // ¡Pero una vez que current existe, es de tipo HTMLInputElement, por lo que\n    // tiene el método focus! ✅\n    if (inputEl \u0026\u0026 inputEl.current) {\n      inputEl.current.focus();\n    }\n  };\n  return (\n    \u003c\u003e\n      {/* Adicionalmente, inputEl solo puede ser usada en elementos input. ¡Sí! */}\n      \u003cinput ref={inputEl} type=\"text\" /\u003e\n      \u003cbutton onClick={onButtonClick}\u003eFocus the input\u003c/button\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgIilQ3wFgAoCzAVwDsNgJa4AVJADxgElaxqYA6sBgALAGIQ01AM4AhfjCYAKAJRwA3hThwA9DrjBaw4CgA2waUjgB3YSLi1qp0wBo4AI35wYSZ6wCeYEgAymhQwGDw1lYoRHCmEBAA1oYA5nCY0HAozAASLACyADI8fDAAoqZIIEi0MFpwaEzS8IZllXAAvIjEMAB0MkjImAA8+cWl-JXVtTAAfEqOzioA3A1NtC1wTPIwirQAwuZoSV1wql1zGg3aenAt4RgOTqaNIkgn0g5ISAAmcDJvBA3h9TsBMAZeFNXjl-lIoEQ6nAOBZ+jddPpPPAmGgrPDEfAUS1pG5hAYvhAITBAlZxiUoRUqjU6m5RIDhOi7iIUF9RFYaqIIP9MlJpABCOCAUHJ0eDzm1oXAAGSKyHtUx9fGzNSacjaPWq6Ea6gI2Z9EUyVRrXV6gC+DRtVu0RBgxuYSnRIzm6O06h0ACpIdlfr9jExSQyOkxTP5GjkPFZBv9bKIDYSmbNpH04ABNFD+CV+nR2636kby+BETCddTlyo27w0zr4HycfC6L0lvUjLH7baHY5Jas7BRMI7AE42uYSUXed6pkY6HtMDulnQruCrCg2oA)\n\nEjemplo creado por [Stefan Baumgartner](https://fettblog.eu/typescript-react/hooks/#useref)\n\n**useReducer**\n\nPuedes usar [Uniones discriminadas](https://www.typescriptlang.org/docs/handbook/advanced-types.html#discriminated-unions) para las acciones del reductor. No olvides definir el tipo de retorno del reductor, de lo contrario Typescript lo inferirá.\n\n```tsx\ntype AppState = {};\ntype Action =\n  | { type: \"SET_ONE\"; payload: string }\n  | { type: \"SET_TWO\"; payload: number };\n\nexport function reducer(state: AppState, action: Action): AppState {\n  switch (action.type) {\n    case \"SET_ONE\":\n      return {\n        ...state,\n        one: action.payload // `payload` es de tipo string\n      };\n    case \"SET_TWO\":\n      return {\n        ...state,\n        two: action.payload // `payload` es de tipo number\n      };\n    default:\n      return state;\n  }\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/C4TwDgpgBAgmYGVgENjQLxQN4F8CwAUKJLAMbACWA9gHZTqFRQA+2UxEAXFAEQICiAFQD6AeQBy-HgG4oYZCAA2VZABNuAZ2AAnCjQDmUfASass7cF14CRggOqiZchcrXcaAVwC2AIwjajaUJCCAAPMCptYCgAMw8acmo6bQhVD1J-AAotVCs4RBQ0ABooZETabhhymgBKSvgkXOxGKA0AdwpgUgALKEyyyloAOg4a5pMmKFJkDWg+ITFJHk4WyagU4A9tOixVtaghw5zivbXaKwGkofklFVUoAHoHqAADG9dVF6gKDVadPX0p0Ce2ms2sC3sjhWEzWGy2OyBTEOQ2OECKiPYbSo3Euw3ed0ezzeLjuXx+UE8vn8QJwQRhUFUEBiyA8imA0P26wgm22f1ydKYxhwQA)\n\n**Hooks personalizados**\n\nSi estás retornando un _array_ en tu Hook personalizdo, querrás evitar la inferencia de tipo dado que Typescript inferirá un tipo de unión (cuando lo que realmente quieres son diferentes tipos en cada posición del _array_). En cambio, utiliza [aserciones const de TS 3.4](https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/#const-assertions):\n\n```tsx\nexport function useLoading() {\n  const [isLoading, setState] = React.useState(false);\n  const load = (aPromise: Promise\u003cany\u003e) =\u003e {\n    setState(true);\n    return aPromise.finally(() =\u003e setState(false));\n  };\n  return [isLoading, load] as const; // infiere [boolean, typeof load] en lugar de (boolean | typeof load)[]\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?target=5\u0026jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCpAD0ljkwFcA7DYCZuRgZyQBkIKACbBmAcwAUASjgBvCnDhoO3eAG1g3AcNFiANHF4wAyjBQwkAXTgBeRMRgA6HklPmkEzCgA2vKQG4FJRV4b0EhWzgJFAAFHBBNJAAuODjcRIAeFGYATwA+GRs8uSDFIzcLCRgoRiQA0rgiGEYoTlj4xMdMUR9vHIlpW2Lys0qvXzr68kUAX0DpxqRm1rgNLXDdAzDhaxRuYOZVfzgAehO4UUwkKH21ACMICG9UZgMYHLAkCEw4baFrUSqVARb5RB5PF5wAA+cHen1BfykaksFBmQA)\n\nDe esta forma, cuando desestructuras realmente obtienes el tipo adecuado dependiendo de la posición de la desestructuración.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eAlternativa: Aserción de un tipo de retorno de tupla\u003c/b\u003e\u003c/summary\u003e\n\nSi [tienes problemas con las aserciones const](https://github.com/babel/babel/issues/9800), también puedes hacer aserciones o definir los tipos de retorno de la función:\n\n```tsx\nexport function useLoading() {\n  const [isLoading, setState] = React.useState(false);\n  const load = (aPromise: Promise\u003cany\u003e) =\u003e {\n    setState(true);\n    return aPromise.finally(() =\u003e setState(false));\n  };\n  return [isLoading, load] as [\n    boolean,\n    (aPromise: Promise\u003cany\u003e) =\u003e Promise\u003cany\u003e\n  ];\n}\n```\n\nUna función utilitaria que automáticamente asigne los tipos también puede ser de ayuda si escribes muchos Hooks personalizados:\n\n```ts\nfunction tuplify\u003cT extends any[]\u003e(...elements: T) {\n  return elements;\n}\n\nfunction useArray() {\n  const numberValue = useRef(3).current;\n  const functionValue = useRef(() =\u003e {}).current;\n  return [numberValue, functionValue]; // type is (number | (() =\u003e void))[]\n}\n\nfunction useTuple() {\n  const numberValue = useRef(3).current;\n  const functionValue = useRef(() =\u003e {}).current;\n  return tuplify(numberValue, functionValue); // type is [number, () =\u003e void]\n}\n```\n\n\u003c/details\u003e\n\nNota, sin embargo, que el equipo de React recomienda que los Hooks personalizados que retornan más de dos valores deberían usar objetos reales en lugar de tuplas.\n\nLecturas adicionales sobre Hooks + Typescript:\n\n- https://medium.com/@jrwebdev/react-hooks-in-typescript-88fce7001d0d\n- https://fettblog.eu/typescript-react/hooks/#useref\n\nSi estás escribiendo una biblioteca de Hooks de React, no olvides que deberías exponer tus tipos para que los usuarios los usen.\n\nEjemplos de bibliotecas con Hooks de React + Typescript\n\n- https://github.com/mweststrate/use-st8\n- https://github.com/palmerhq/the-platform\n- https://github.com/sw-yx/hooks\n\n[Algo que añadir? Abre un _issue_](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## Componentes de clase\n\nDentro de Typescript, `React.Component` es un tipo genérico (alias `React.Component\u003cPropType, StateType\u003e`), por lo que quieres añadirle parámetros (opcionales) de prop y estado:\n\n```tsx\ntype MyProps = {\n  // usar `interface` también está bien\n  message: string;\n};\ntype MyState = {\n  count: number; // así\n};\nclass App extends React.Component\u003cMyProps, MyState\u003e {\n  state: MyState = {\n    // segunda anotación opcional para una mejor inferencia de tipos\n    count: 0\n  };\n  render() {\n    return (\n      \u003cdiv\u003e\n        {this.props.message} {this.state.count}\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCmATzCTgFlqAFHMAZzgF44BvCuHAD0QuAFd2wAHYBzOAANpMJFEzok8uME4oANuwhwIAawFwQSduxQykALjjsYUaTIDcFAL4fyNOo2oAZRgUZW4+MzQIMSkYBykxEAAjFTdhUV1gY3oYAAttLx80XRQrOABBMDA4JAAPZSkAE05kdBgAOgBhXEgpJFiAHiZWCA4AGgDg0KQAPgjyQSdphyYpsJ5+BcF0ozAYYAgpPUckKKa4FCkpCBD9w7hMaDgUmGUoOD96aUwVfrQkMyCKIxOJwAAMZm8ZiITRUAAoAJTzbZwIgwMRQKRwOGA7YDRrAABuM1xKN4eW07TAbHY7QsVhsSE8fAptKWynawNinlJcAGQgJxNxCJ8gh55E8QA)\n\nNo olvides que puedes exportar/importar/extender estos tipos/interfaces para su reutilización.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003e¿Por qué anotar `state` dos veces?\u003c/b\u003e\u003c/summary\u003e\n\nNo es estrictamente necesario antotar la propiedad de clase `state`, pero permite una mejor inferencia de tipos cuando se accede a `this.state` y también al inicializar el estado.\n\nEsto ocurre porque funcionan de dos formas diferentes, el segundo parámetro del tipo genérico permitirá que `this.setState()` funcione correctamente, porque ese método viene de la clase base, pero al inicializar `state` dentro del componente sobreescribe la implementación base por lo que te tienes que asegurar de decirle al compilador que en realidad no estás haciendo nada distinto.\n\n[Consulta el comentario de @ferdaber aquí](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/57).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003e\u003cb\u003eNo hay necesidad de anotar con \u003ccode\u003ereadonly\u003c/code\u003e\u003c/b\u003e\u003c/summary\u003e\n\nA menudo ves código en ejemplos que incluyen `readonly` para marcar las props y el estado como inmutables:\n\n```tsx\ntype MyProps = {\n  readonly message: string;\n};\ntype MyState = {\n  readonly count: number;\n};\n```\n\nEsto no es necesario, porque `React.Component\u003cP,S\u003e` ya los marca como inmutables. ([¡Consulta el PR y el debate!](https://github.com/DefinitelyTyped/DefinitelyTyped/pull/26813))\n\n\u003c/details\u003e\n\n**Métodos de clase**: Hazlo como de costumbre, pero solo recuerda que cualquier argumento para tus funciones también debe tener tipos:\n\n```tsx\nclass App extends React.Component\u003c{ message: string }, { count: number }\u003e {\n  state = { count: 0 };\n  render() {\n    return (\n      \u003cdiv onClick={() =\u003e this.increment(1)}\u003e\n        {this.props.message} {this.state.count}\n      \u003c/div\u003e\n    );\n  }\n  increment = (amt: number) =\u003e {\n    // así\n    this.setState(state =\u003e ({\n      count: state.count + amt\n    }));\n  };\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHrxgAeAN5wQSBigDmSAFxw6MKMB5q4AXwA0cRWggBXHjG09rIAEZIoJgHwWKcHTBTccAC8FnBWtvZwAAwmANw+cET8bgAUAJTe5L6+RDDWUDxwKQnZcLJ8wABucBA8YtTAaADWQfLpwV4wABbAdCIGaETKdikAjGnGHiWlFt29ImA4YH3KqhrGsz19ugFIIuF2xtO+sgD0FZVTWdlp8ddH1wNDMsFFKCCRji5uGUFe8tNTqc4A0mkg4HM6NNISI6EgYABlfzcFI7QJ-IoA66lA6RNF7XFwADUcHeMGmxjStwSxjuxiAA)\n\n**Propiedades de clase**: Si necesitas declarar propiedades de clase para un uso posterior, simplemente declaralas como `state`, pero sin asignación:\n\n```tsx\nclass App extends React.Component\u003c{\n  message: string;\n}\u003e {\n  pointer: number; // así\n  componentDidMount() {\n    this.pointer = 3;\n  }\n  render() {\n    return (\n      \u003cdiv\u003e\n        {this.props.message} and {this.pointer}\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHrxgAeAN4U4cEEgYoA5kgBccOjCjAeGgNwUAvgD44i8sshHuUXTwCuIAEZIoJuAHo-OGpgAGskOBgAC2A6JTg0SQhpHhgAEWA+AFkIVxSACgBKGzjlKJiRBxTvOABeOABmMzs4cziifm9C4ublIhhXKB44PJLlOFk+YAA3S1GxmzK6CpwwJdV1LXM4FH4F6KXKp1aesdk-SZnRgqblY-MgA)\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## Tipos de defaultProps\n\nPara Typescript 3.0+, la inferencia de tipos [debe funcionar](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html), sin embargo [algunos casos extremos aún son problemáticos](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/61). Simplemente asigna tus tipos como de costumbre, excepto que no uses `React.FC`.\n\n```tsx\n// ////////////////\n// componentes de función\n// ////////////////\ntype Props = { age: number } \u0026 typeof defaultProps;\nconst defaultProps = {\n  who: \"Johny Five\"\n};\n\nconst Greet = (props: Props) =\u003e {\n  /*...*/\n};\nGreet.defaultProps = defaultProps;\n```\n\nPara los **componentes de clase**, hay [un par de formas de hacerlo](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/pull/103#issuecomment-481061483) (incluido el uso del tipo utilitario `Pick`) pero la recomendación es \"revertir\" la definición de las props:\n\n```tsx\ntype GreetProps = typeof Greet.defaultProps \u0026 {\n  age: number;\n};\n\nclass Greet extends React.Component\u003cGreetProps\u003e {\n  static defaultProps = {\n    name: \"world\"\n  };\n  /*...*/\n}\n\n// ¡Hay chequeo de tipos! ¡No se requieren aserciones de tipo!\nlet el = \u003cGreet age={3} /\u003e;\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003e¿Por qué React.FC interfiere con las defaultProps?\u003c/summary\u003e\n\nPuedes chequear los debates aquí:\n\n- https://medium.com/@martin_hotell/10-typescript-pro-tips-patterns-with-or-without-react-5799488d6680\n- https://github.com/DefinitelyTyped/DefinitelyTyped/issues/30695\n- https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/87\n\nEsto es solo el estado actual y podría ser solucionado en el futuro.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n \u003csummary\u003eTypescript 2.9 y versiones anteriores\u003c/summary\u003e\n\nPara Typescript 2.9 y versiones anteriores, hay más de una forma de hacerlo, pero el mejor consejo que hemos visto hasta ahora es:\n\n```ts\ntype Props = Required\u003ctypeof MyComponent.defaultProps\u003e \u0026 {\n  /* additional props here */\n};\n\nexport class MyComponent extends React.Component\u003cProps\u003e {\n  static defaultProps = {\n    foo: \"foo\"\n  };\n}\n```\n\nNuestra recomendación anterior usaba la funcionalidad `Partial type` de Typescript, que significa que la interfaz actual cumplirá con una versión parcial de la interfaz envuelta. ¡De esa forma podemos extender defaultProps sin ningún cambio en los tipos!\n\n```ts\ninterface IMyComponentProps {\n  firstProp?: string;\n  secondProp: IPerson[];\n}\n\nexport class MyComponent extends React.Component\u003cIMyComponentProps\u003e {\n  public static defaultProps: Partial\u003cIMyComponentProps\u003e = {\n    firstProp: \"default\"\n  };\n}\n```\n\nEl problema con este enfoque es que causa complejos problemas con la inferencia de tipos en conjunto con `JSX.LibraryManagedAttributes`. Básicamente ocasiona que el compilador piensa que cuando se crea una expresión JSX con ese componente, todas sus props son opcionales.\n\n[Consulta el comentario de @ferdaber aquí](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/57).\n\n\u003c/details\u003e\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## ¿Tipos o interfaces?\n\nLas interfaces (`interface`) son diferentes de los tipos (`type`) en TypeScript, pero tienen usos muy similares en lo que concierne a los casos de usos comunes en React. Esta es una regla útil:\n\n- siempre usa `interface` para las definiciones de API pública cuando se está escribiendo una biblioteca o las definiciones de tipos de ambiente de una biblioteca de terceros.\n\n\\_ considera usar `type` para las props y estado de tus componentes de React, porque tiene más restricciones.\n\nLos tipos son útiles para los tipos de unión (p. ej. `type MyType = TypeA | TypeB`) mientras las interfaces son mejores para declarar formas de dicionario y luego `implementarlas` o `extenderlas`.\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n    \u003cb\u003eTabla útil para tipos vs. interfaces\u003c/b\u003e\n  \u003c/summary\u003e\nEs un tema con muchos matices, no te preocupes demasiado por esto. He aquí un gráfico útil:\n\n![https://pbs.twimg.com/media/DwV-oOsXcAIct2q.jpg](https://pbs.twimg.com/media/DwV-oOsXcAIct2q.jpg) (fuente: [Karol Majewski](https://twitter.com/karoljmajewski/status/1082413696075382785))\n\n\u003c/details\u003e\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## Ejemplos básicos de Prop Types\n\n```tsx\ntype AppProps = {\n  message: string;\n  count: number;\n  disabled: boolean;\n  /** ¡array de un tipo! */\n  names: string[];\n  /** literales de string que especifican valores exactos de string, con un tipo de unión que los une */\n  status: \"waiting\" | \"success\";\n  /** cualquier objeto siempre y cuando no utilices sus propiedades (noi es común) */\n  obj: object;\n  obj2: {}; // casi igual que `object`, exactamente los mismo que `Object`\n  /** un objeto con propiedades definidas (preferido) */\n  obj3: {\n    id: string;\n    title: string;\n  };\n  /** ¡array de objetos! (común) */\n  objArr: {\n    id: string;\n    title: string;\n  }[];\n  /** cualquier función siempre y cuando no la invoques (no recomendado) */\n  onSomething: Function;\n  /** función que no toma ni devuelve nada (MUY COMÚN) */\n  onClick: () =\u003e void;\n  /** función con una prop nombrada (MUY COMÚN) */\n  onChange: (id: number) =\u003e void;\n  /** sintaxis alternativa de tipo función que toma un evento (MUY COMÚN) */\n  onClick(event: React.MouseEvent\u003cHTMLButtonElement\u003e): void;\n  /** una prop opcional (!MUY COMÚN!) */\n  optional?: OptionalType;\n};\n```\n\nNota que hemos usado `/** commentarios */` con estilo TSDoc para cada prop. Puedes y te recomendamos dejar comentarios descriptivos en los componentes reutilizables. Para un ejemplo más completo y comentarios, consulta nuestra sección de [comentar componentes](/AVANZADO.md#componentes-comentados) en la guía avanzada.\n\n## Ejemplos útiles de tipos de props en React\n\n```tsx\nexport declare interface AppProps {\n  children1: JSX.Element; // mal, no tiene en cuenta los arreglos\n  children2: JSX.Element | JSX.Element[]; // más o menos, no acepta funciones\n  children3: React.ReactChildren; // a pesar del nombre, no es para nada apropieado; es un utilitario\n  children4: React.ReactChild[]; // mejor\n  children: React.ReactNode; // el mejor, acepta todo\n  functionChildren: (name: string) =\u003e React.ReactNode; // tipo recomendado para render prop del tipo función como hijo\n  style?: React.CSSProperties; // para pasar props de estilo\n  onChange?: React.FormEventHandler\u003cHTMLInputElement\u003e; // ¡Eventos de formulario! el parámetro genérico es el tipo de event.target\n  props: Props \u0026 React.PropsWithoutRef\u003cJSX.IntrinsicElements[\"button\"]\u003e; // para imitar todas las props de un elemento button sin su ref\n}\n```\n\n\u003cdetails\u003e\n \u003csummary\u003e\u003cb\u003e¿JSX.Element vs. React.ReactNode?\u003c/b\u003e\u003c/summary\u003e\n\nCitando a [@ferdaber](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/57): Una explicación más técnica consiste en que un nodo válido de React no es lo mismo que lo que retorna `React.createElement`. Sin importar el componente que se termina renderizando, `React.createElement` siempre retorna un objeto, que es la interfaz `JSX.Element`, pero `React.ReactNode` es el conjunto de todos los posibles valores de retorno de un componente.\n\n- `JSX.Element` -\u003e Valor de retorno de `React.createElement`\n- `React.ReactNode` -\u003e Valor de retorno de un componente\n  \u003c/details\u003e\n\n[Más discusiones: Where ReactNode does not overlap with JSX.Element](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/129)\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## getDerivedStateFromProps\n\nAntes de que comiences a usar `getDerivedStateFromProps`, por favor consulta la [documentación](https://es.reactjs.org/docs/react-component.html#static-getderivedstatefromprops) y [Probablemente no necestas estado derivado](https://es.reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html). El estado derivado puede conseguirse facilmente utilizando Hooks, los que también pueden ayudar a configurar fácilmente la memoización.\n\nAquí hay algunas formas en las que puedes anotar `getDerivedStateFromProps`\n\n1. Si has establecido explícitamente los tipos de tu estado derivado y quieres asegurarte de que el valor de retorno de `getDerivedStateFromProps` lo cumple.\n\n```tsx\nclass Comp extends React.Component\u003cProps, State\u003e {\n  static getDerivedStateFromProps(\n    props: Props,\n    state: State\n  ): Partial\u003cState\u003e | null {\n    //\n  }\n}\n```\n\n2. Cuando quieres que el valor de retorno de la función determine tu estado.\n\n```tsx\nclass Comp extends React.Component\u003c\n  Props,\n  ReturnType\u003ctypeof Comp[\"getDerivedStateFromProps\"]\u003e\n\u003e {\n  static getDerivedStateFromProps(props: Props) {}\n}\n```\n\n3. Cuando quieres estado derivado con otros campos de estado y memoización\n\n```tsx\ntype CustomValue = any;\ninterface Props {\n  propA: CustomValue;\n}\ninterface DefinedState {\n  otherStateField: string;\n}\ntype State = DefinedState \u0026 ReturnType\u003ctypeof transformPropsToState\u003e;\nfunction transformPropsToState(props: Props) {\n  return {\n    savedPropA: props.propA, // guardar para memoización\n    derivedState: props.propA\n  };\n}\nclass Comp extends React.PureComponent\u003cProps, State\u003e {\n  constructor(props: Props) {\n    super(props);\n    this.state = {\n      otherStateField: \"123\",\n      ...transformPropsToState(props)\n    };\n  }\n  static getDerivedStateFromProps(props: Props, state: State) {\n    if (isEqual(props.propA, state.savedPropA)) return null;\n    return transformPropsToState(props);\n  }\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoUSWOYAZwFEBHAVxQBs5tcD2IATFHQAWAOnpJWHMuQowAnmCRwAwizoxcANQ4tlAXjgoAdvIDcFYMZhIomdMoAKOMHTgBvCnDhgXAQQAuVXVNEB12PQtyAF9La1t7NGUAESRMKyR+AGUYFBsPLzgIGGFbHLykADFgJHZ+II0oKwBzKNjyBSU4cvzDVPTjTJ7lADJEJBgWKGMAFUUkAB5OpAhMOBgoEzpMaBBnCFcZiGGAPijMFmMMYAhjdc3jbd39w+PcmwAKXwO6IJe6ACUBXI3iIk2mwO83joKAAbpkXoEfC46KJvmA-AAaOAAehxcBh8K40DgICQIAgwAAXnkbsZCt5+LZgPDsu8kEF0aj0X5CtE2hQ0OwhG4VLgwHAkAAPGzGfhuZDoGCiRxTJBi8C3JDWBb-bGnSFwNC3RosDDQL4ov4ooGeEFQugsJRQS0-AFRKHrYT0UQaCpwQx2z3eYqlKDDaq1epwABEAEYAEwAZhjmIZUNEmY2Wx2UD2KKOw1drgB6f5fMKfpgwDQcGaE1STVZEZw+Z+xd+cD1BPZQWGtvTwDWH3ozDY7A7aP82KrSF9cIR-gBQLBUzuxhY7HYHqhq4h2ceubbryLXPdFZiQA)\n\n## Formularios y Eventos\n\nSi el rendimiento no es un problema, tener los manejadores de eventos en línea es la forma más fácil dado que simplemente puedes usar [la inferencia de tipos y el tipado contextual](https://www.typescriptlang.org/docs/handbook/type-inference.html#contextual-typing):\n\n```tsx\nconst el = (\n  \u003cbutton\n    onClick={event =\u003e {\n      /* ... */\n    }}\n  /\u003e\n);\n```\n\nPero si necesitas definir tus manejadores de eventos de forma separada, las herramientas del IDE pueden ser útiles en este caso, dado que las definiciones de @type vienen con muchos tipos. Escribe lo que estás buscando y usualmente el autocompletamiento te ayudará. Aquí se muestra el caso de `onChange` para un evento de formulario:\n\n```tsx\nclass App extends React.Component\u003c\n  {},\n  {\n    // sin props\n    text: string;\n  }\n\u003e {\n  state = {\n    text: \"\"\n  };\n\n  // anotar el tipo en la parte DERECHA de =\n  onChange = (e: React.FormEvent\u003cHTMLInputElement\u003e): void =\u003e {\n    this.setState({ text: e.currentTarget.value });\n  };\n  render() {\n    return (\n      \u003cdiv\u003e\n        \u003cinput type=\"text\" value={this.state.text} onChange={this.onChange} /\u003e\n      \u003c/div\u003e\n    );\n  }\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHrxgAeCnDgBvAL4AaBcs2KA9Drg8IcMDjB1tcblwBccOjCjAeAcwDcmlRQB8W8ovso3HAAvL6KilYwtgBE0R7ulH5wepYAnmBOznAQPIgAkgDiABIAKnAAFij8dsB8SNmYIZo5YpUu9aEAFEi2QhgiAGLQIACiAG4ysqUAsgAyeTxgAK4wI9RIIDJeAJS2YxC1IT5KFjDlwHQidEgwAMowgUidSpacUewiaEtQRDwwJSgoM4biIxihqEt6iptglFCpYXBfnUoJ1tmFwkQYN9cp0LIpZHxgGMvHjwrInMt4DB0khgtFItE4GCIbSlGcLlcHtwRJEVNkeK0qsDgmzzpcWm1gXydCSkuE4LIdITiRYYR4KCogA)\n\nEn lugar de anotar los tipos de los argumentos y los valore de retorno con `React.FormEvent\u003c\u003e` y `void`, alternativamente puedes aplicar los tipos al manejador de eventos mismo (_contribución de @TomasHubelbauer_):\n\n```tsx\n  // anotar el tipo en la parte IZQUIERDA de =\n  onChange: React.ChangeEventHandler\u003cHTMLInputElement\u003e = (e) =\u003e {\n    this.setState({text: e.currentTarget.value})\n  }\n```\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003cb\u003e¿Por qué dos formas de hacer lo mismo?\u003c/b\u003e\u003c/summary\u003e\n\nEl primer método utiliza una firma inferida para el método `(e: React.FormEvent\u003cHTMLInputElement\u003e): void` y la segunda fuerza un tipo del delegado proporcioanado por `@types/react`. O sea que `React.ChangeEventHandler\u003c\u003e` es simplemente un tipo \"bendecido\" por `@types/react`, mientras puedes ver el método inferido como más... _hecho artesanalmente_. De cualquier forma es un buen patrón a conocer. [Mira nuestro PR de Github PR para más información](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/pull/24).\n\n\u003c/details\u003e\n\n**Tipado de onSubmit, con componentes no controlados en un formulario**\n\nSi no te importa mucho el tipo del evento, simplemente puedes utilizar React.SyntheticEvent. Si tu formulario objetivo tiene _inputs_ con nombres personalizados a los que quisieras acceder, puedes utilizar la extensión de tipos:\n\n```tsx\n\u003cform\n  ref={formRef}\n  onSubmit={(e: React.SyntheticEvent) =\u003e {\n    e.preventDefault();\n    const target = e.target as typeof e.target \u0026 {\n      email: { value: string };\n      password: { value: string };\n    };\n    const email = target.email.value; // typechecks!\n    const password = target.password.value; // typechecks!\n    // etc...\n  }}\n\u003e\n  \u003cdiv\u003e\n    \u003clabel\u003e\n      Email:\n      \u003cinput type=\"email\" name=\"email\" /\u003e\n    \u003c/label\u003e\n  \u003c/div\u003e\n  \u003cdiv\u003e\n    \u003clabel\u003e\n      Password:\n      \u003cinput type=\"password\" name=\"password\" /\u003e\n    \u003c/label\u003e\n  \u003c/div\u003e\n  \u003cdiv\u003e\n    \u003cinput type=\"submit\" value=\"Log in\" /\u003e\n  \u003c/div\u003e\n\u003c/form\u003e\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtCAOwGctoRlM4BeRYmAOgFc6kLABQBKClVoM4AMSbs4o9gD4FFOHAA8mJmrhFMbAN7aozJJgC+u2gGVeAIxDAYRoUgBcndDxsBPGjAAFkgwwGgAogBuSAEiynCGuupI3GBE0QEAIuYovAA2MKIA3Elw1PTwMChQAOYh8ilVtfUodHAwvmBIEKyN1XXwAGQJpckgKMB5noZwkSh5vB5wDFDANDVwFiXk6rtwYK10AO7QACbTs-OLnitrG1ulDzu75VJI45PyTQPc7xN53DmCyQRTgAHowe1Okg0ME0ABrOgAQlKr3gBzoxzOX36IVShxOUFOgKuIPBkI6XVhMMRKOe6ghcBCaG4rN0Fis5CUug0p2AkW59M0eRQ9iQeUFe3U4Q+U1GmjWYF4lWhbAARH9Jmq4DQUCAkOrNXltWDJbsNGCRWKJTywXyBTz7Wb1BoreLnbsAAoEs7ueUaRXKqFddUYrFE7W6-Whn0R8Eei1um3PC1Ox38hOBlUhtV0BxOGDaoGLdUAGQgGzWJrNqYzFAtJhAgpEQA)\n\nPor supuesto, si estás construyendo algún tipo de formulario de consideración, [deberías usar Formik](https://jaredpalmer.com/formik), que está escrito en TypeScript.\n\n## Contexto\n\nUsar `React.createContext` y [getters de contexto](https://kentcdodds.com/blog/application-state-management-with-react/) para hacer un `createCtx` **sin `defaultValue`, pero sin tener que chequear por `undefined`**:\n\n```tsx\n// Crea un contexto sin un valor por defecto inicial\n// sin tener que hacer chequeos de undefined todo el tiempo\nfunction createCtx\u003cA\u003e() {\n  const ctx = React.createContext\u003cA | undefined\u003e(undefined);\n  function useCtx() {\n    const c = React.useContext(ctx);\n    if (!c) throw new Error(\"useCtx must be inside a Provider with a value\");\n    return c;\n  }\n  return [useCtx, ctx.Provider] as const; // haz que TypeScript infiera una tupla, no un arreglo de tipos de unión\n}\n\n// uso\n\nexport const [useCtx, SettingProvider] = createCtx\u003cstring\u003e(); // Se especifica el tipo, ¡pero sin necesidad de especificar el valor de antemano!\nexport function App() {\n  const key = useCustomHook(\"key\"); // Se obtiene un valor de un hook, debe estar en un componente\n  return (\n    \u003cSettingProvider value={key}\u003e\n      \u003cComponent /\u003e\n    \u003c/SettingProvider\u003e\n  );\n}\nexport function Component() {\n  const key = useCtx(); // ¡Aún se puede usar sin chequeos de null!\n  return \u003cdiv\u003e{key}\u003c/div\u003e;\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtCAOwGd4BXOpAYWZlwAkIIBrOAF44ACj5IAngC44DKMBoBzAJRCAfHADeFOHGr14AbQYoYSADSykMAMoxTSALpDExGADpmSOw5GaAvso6cEQwjFA0svZmhuISjhT+FAD0yXpEDnq0ZgAe8ADuwDAAFnA0EHCMYNjZcAAmSJgojAA2MABqKC2MSClphSUQjPDFKABuCopwnPUVjDQNmApIdXrFSGgCXS3T69OgveSY8xjAtOmoZqwwOQA8AIJqIqra5Lr6DHo3LsjoHmgZK7ZJB5B5wAA+lQWjWWdSe80WsOUAG5gscaKdzl5rjlnlpgu9aJ80D83J4WKxgXkRBgciiCXBgJhRABCNCqEo4fJlJDcgCiUBwUBEACJsd8QBw4AAjJCM+jABpwFBwAAKOAmDSgcAGpRVYy6PRF9LeuhC1nCkTQqNNSVNoUtcEM4pyllp7nVEE1SCgzhQdCyBmRcFScBAKHEcAAKhIwN4AcAwPAFJgfcrplUWhYyhB4ChIihBSgJHAIMz5mdIjBY0g6IkKH1KnQUIpDhQQZBYIHPs6KTdLDZrDBJp7vb6XADLmwbrc5JMniiQ2k6HG0EyS9W45ZpcMczyVtMKiuNuu4AbunKqjUaDAWe2cp2sCdh+d7mAwHjXoSDHA4i5sRw3C8HwopxMawahq2eZnoaco1HgKrFMBliSp8sryum1DgLQSA3sEDoRKIDK3IOMDDkoo6Kmm549IImhxP4agMrotyUthNC4fAyRMaaLHJKR5GKJRWo8boJp2h20BPhiL6RGxkAcTen7BB88B-sILrPBBaRoPmUTAC0OxeDqRRIbuNCtDsaDrJsd72hahG3HUwBjGo9GSP4tzJM5rk2v4QA)\n\nUsando `React.createContext` y `useContext` para hacer un `createCtx` con _setters_ de contexto al estilo [`unstated`](https://github.com/jamiebuilds/unstated):\n\n```tsx\nexport function createCtx\u003cA\u003e(defaultValue: A) {\n  type UpdateType = React.Dispatch\u003cReact.SetStateAction\u003ctypeof defaultValue\u003e\u003e;\n  const defaultUpdate: UpdateType = () =\u003e defaultValue;\n  const ctx = React.createContext({\n    state: defaultValue,\n    update: defaultUpdate\n  });\n  function Provider(props: React.PropsWithChildren\u003c{}\u003e) {\n    const [state, update] = React.useState(defaultValue);\n    return \u003cctx.Provider value={{ state, update }} {...props} /\u003e;\n  }\n  return [ctx, Provider] as const; // alternativamente, [typeof ctx, typeof Provider]\n}\n\n// uso\n\nconst [ctx, TextProvider] = createCtx(\"someText\");\nexport const TextContext = ctx;\nexport function App() {\n  return (\n    \u003cTextProvider\u003e\n      \u003cComponent /\u003e\n    \u003c/TextProvider\u003e\n  );\n}\nexport function Component() {\n  const { state, update } = React.useContext(TextContext);\n  return (\n    \u003clabel\u003e\n      {state}\n      \u003cinput type=\"text\" onChange={e =\u003e update(e.target.value)} /\u003e\n    \u003c/label\u003e\n  );\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCpAD0ljkwFcA7DYCZuNIlGJAYRjUAPAEEAfAAoAJkkwpGAGxgA1FIsZIAXHFEBKOAG8KcODACeYJHACqYabyQAVS9YC8iYjAB0AEWAAzmC8aAAWwsjoPgDKSDDRMI6ibBzCFlYQmHCy8kqq6pri4gDcJlwcAfA5Csp2Dnw6dY4uVnAekgZu4tlyNfkaSKXkpmgV8BjUbZ5R3tyofPwcfNQwksbDpnCVjjrVeWoDADRlpoz2Oz25ted8ZQC+ekOmTKww7JwACjgAbsCyUJIwDgwAEdJEMN4vhAQQB1YAwUL8ULARTSIjMYSGO7iAzrTblZiVOAAbW2fEOcDO9SQAF0puCfIwAkgEo4ZL19gUkI8TnAiDBGFBOMIJpCfn8kFA4N8uW5DIYtolyZSbtY7ncjN4tUDoQENQB6Er3Mr8wWcYkTClQ37-OkoAIEyrFOD6-VwdR8IW8YDfJCKcwU4npJCZLhCCnB0PWiVQGkUO4UCiuykBFAAcyQifIo0J8At4bgThoMGjtqmc0cgmokgARAFcM5izWeeQaHRxmNC8XFsxlvAPBMhm3oFgWClOKIwGAOkYTXEzXBJLzhEWVqXJeJeaZhItwBwkL2XZuNtv9auS+L-sfTC2E63aCOGGO3hw4LvIMwD6tcWUc0SFWSSAUlSjhwBqHgMt4TICEsxaSOePZ9i2pimkKi7LooKAAEZ+te+JGIBd74XAwjAMwYCMPAwZuDWfY1nAHBIigzAZnK7jdCBfCSEg3iJFAGY+DKAx6AaeGnphOGKHht5AA)\n\nUn [versión basada en useReducer](https://gist.github.com/sw-yx/f18fe6dd4c43fddb3a4971e80114a052) también puede resultar útil.\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003cb\u003eContexto mutable usando un envoltorio de componente de clase\u003c/b\u003e\u003c/summary\u003e\n\n_Contribuido por: [@jpavon](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/pull/13)_\n\n```tsx\ninterface ProviderState {\n  themeColor: string;\n}\n\ninterface UpdateStateArg {\n  key: keyof ProviderState;\n  value: string;\n}\n\ninterface ProviderStore {\n  state: ProviderState;\n  update: (arg: UpdateStateArg) =\u003e void;\n}\n\nconst Context = React.createContext({} as ProviderStore); // type assertion on empty object\n\nclass Provider extends React.Component\u003c{}, ProviderState\u003e {\n  public readonly state = {\n    themeColor: \"red\"\n  };\n\n  private update = ({ key, value }: UpdateStateArg) =\u003e {\n    this.setState({ [key]: value });\n  };\n\n  public render() {\n    const store: ProviderStore = {\n      state: this.state,\n      update: this.update\n    };\n\n    return (\n      \u003cContext.Provider value={store}\u003e{this.props.children}\u003c/Context.Provider\u003e\n    );\n  }\n}\n\nconst Consumer = Context.Consumer;\n```\n\n\u003c/details\u003e\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## forwardRef/createRef\n\nConsulta la sección de [Hooks](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/blob/master/README.md#hooks) para `useRef`.\n\n`createRef`:\n\n```tsx\nclass CssThemeProvider extends React.PureComponent\u003cProps\u003e {\n  private rootRef = React.createRef\u003cHTMLDivElement\u003e(); // así\n  render() {\n    return \u003cdiv ref={this.rootRef}\u003e{this.props.children}\u003c/div\u003e;\n  }\n}\n```\n\n`forwardRef`:\n\n```tsx\ntype Props = { children: React.ReactNode; type: \"submit\" | \"button\" };\nexport type Ref = HTMLButtonElement;\nexport const FancyButton = React.forwardRef\u003cRef, Props\u003e((props, ref) =\u003e (\n  \u003cbutton ref={ref} className=\"MyClassName\" type={props.type}\u003e\n    {props.children}\n  \u003c/button\u003e\n));\n```\n\nSi estás obteniendo las props de un componente que pasa las refs, usa [`ComponentPropsWithRef`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a05cc538a42243c632f054e42eab483ebf1560ab/types/react/index.d.ts#L770).\n\nMás información: https://medium.com/@martin_hotell/react-refs-with-typescript-a32d56c4d315\n\nTambién puede que quieras hacer [Renderizado condicional con `forwardRef`](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/167).\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## Portales\n\nUso de `ReactDOM.createPortal`:\n\n```tsx\nconst modalRoot = document.getElementById(\"modal-root\") as HTMLElement;\n// asumiento que tu archivo html tiene un div con id 'modal-root';\n\nexport class Modal extends React.Component {\n  el: HTMLElement = document.createElement(\"div\");\n\n  componentDidMount() {\n    modalRoot.appendChild(this.el);\n  }\n\n  componentWillUnmount() {\n    modalRoot.removeChild(this.el);\n  }\n\n  render() {\n    return ReactDOM.createPortal(this.props.children, this.el);\n  }\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoUSWRYmAEQHkBZObXAo9GAWgBNcZchTQQAdgGd4ICHxQAbBBAjwAvHAFoAriCRiYAOgDmSGAFF5SXfoBCATwCSfABQAiGXPk8cK1wEo4FAk4AAkAFWYAGQsrPRgAbgoAeiTAiQkdYDEjOCy4OwgtKDgACxgQeTZgS1KgwI1gADc4AHdgGBLcvgIPBW9lGHxE4XIkAA9qeDR5IODmWQU4cZg9PmDkbgMAYVxIMTi4AG8KOCX5AC5QiOjLazUNCG07gzQuFZi7tz4m-2GTuFE4HEcXowD48y0+mcAWO5FOp16igGBhQYDAqy2JWqLg6wAkBiQ8j8w1OAF8KP9AXs4gB1aryACqYhkkJg0KO-wRCyRKgMRBkjSQmOxzlx+MJxP+5JGpyIYj4SCg7Nh8LgRBgRTEtG4TGYLzeSAACtAYApRVj8WAcGB8WgsfI+HKADRwMUEokkuDS0lAA)\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\u003cb\u003eContexto del ejemplo\u003c/b\u003e\u003c/summary\u003e\n\nEste ejemplo está basado en el ejemplo [Event Bubbling Through Portal](https://es.reactjs.org/docs/portals.html#event-bubbling-through-portals) de la documentación de React.\n\n\u003c/details\u003e\n\n## Barreras de error\n\n_No escrito aún._\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## Concurrent React/React Suspense\n\n_No escrito aún._ observa \u003chttps://github.com/sw-yx/fresh-async-react\u003e para más sobre React Suspense y Time Slicing.\n\n[¿Algo que añadir? Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n# Manual básico de resolución de problemas: Tipos\n\n\u003e ⚠️ ¿Has leído la [página de preguntas frecuentes de TypeScript](https://github.com/microsoft/TypeScript/wiki/FAQ)?) !Tu respuesta podría estar allí!\n\n¿Te encuentras ante extraños errores de tipo? No estás solo. Esta es la parte más difícil de usar TypeScript con React. Sé paciente (después de todo estás aprendiendo un nuevo lenguaje). Sin embargo, mientras mejor te vuelvas en esto, ¡menos tiempo estarás trabajando _en contra_ del compilador y más tiempo estará el compilador trabajando _para_ ti!\n\nIntenta evitar asignar el tipo `any` tanto como te sea posible para experimentar los máximos beneficios de TypeScript. En cambio, intentemos familiarizarnos con algunas estrategias comunes para resolver esos problemas.\n\n## Tipos de unión y seguro de tipo\n\nLos tipos de unión son útiles para resolver algunos de estos problemas con el tipado:\n\n```tsx\nclass App extends React.Component\u003c\n  {},\n  {\n    count: number | null; // así\n  }\n\u003e {\n  state = {\n    count: null\n  };\n  render() {\n    return \u003cdiv onClick={() =\u003e this.increment(1)}\u003e{this.state.count}\u003c/div\u003e;\n  }\n  increment = (amt: number) =\u003e {\n    this.setState(state =\u003e ({\n      count: (state.count || 0) + amt\n    }));\n  };\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCtAGxQGc64BBMMOJADxiQDsATRsnQwAdAGFckHrxgAeCnDgBvAL4AaBcs2K0EAK48YALjg89IAEZIocAD6m91agG44AejdxqwANZI4MAAWwHSaKhQAfFrkinQwKNxwALzRijr6hiZmTmHOmkT81gAUAJSpaUQwelA8cLJ8wABucBA8Yt5oPklKpclRQSEiwDxoRCAyRQCMJSoRSgN0InEJSCK6BjAqsm4NjRF5MXDhh8OjSOOGyXBFKCDGDpbWZUlRStoBwYt0SDAAyvHcIrLRIva5vQ5pODrTLXYGraHwWz2AAMZQA1HBbjB3ioSiUDooVAcVEA)\n\n**Seguro de tipo**: A veces los tipos de unión resuelven el problema en un área, pero crean otro debajo en la cadena. Si `A` y `B` son ambos tipos de objeto, `A | B` no es \"o bien A o bien B\", es \"A o B (o ambos)\", lo que causa alguna confusión si esperabas que fuera lo primero. Aprende como escribir chequeos, seguros, y aserciones (también consulta la sección de renderizado condicional debajo). Por ejemplo:\n\n```ts\ninterface Admin {\n  role: string;\n}\ninterface User {\n  email: string;\n}\n\n// Método 1: usar la palabra clave `in`\nfunction redirect(user: Admin | User) {\n  if (\"role\" in user) {\n    // Usa el operador `in` para seguros de tipo desde TS 2.7+\n    routeToAdminPage(user.role);\n  } else {\n    routeToHomePage(user.email);\n  }\n}\n\n// Método 2: Seguro de tipo personalizado, hace lo mismo en versiones anteriores de TS o donde `in` no es suficiente\nfunction isAdmin(user: Admin | User): user is Admin {\n  return (user as any).role !== undefined;\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoC4AOxiSk3STgEEATEGuAbwrjhwAbJAC44AZxhQaAcwDcFAL5Va9RmmYBVcfR584SECmCCxk6dXlKKFTAFdqGYBGoCIdugBUI7TtQAKKDJIABTiwDLUwJjA9ACUeuT80XBhEVExugC8OQR2OlAIEML4CbxJ-AJIMHZQrvi+NGQVinDWlOT2jjDOrjgeSN4AErhIgcFpkdGxUGX6KZMZM3A5WQSGxoKliZVVNXUEIyBIYEFIzfzK5FcUAPS3cACy1QAWEGxwAIxi+cwABjQ-nAANZIACeAHdoGxbA4nC4qmxgEQMCFflAxI1XAAfODaeI7ODREIAIiESBJRNc6LKcHucF+cBgL3+gLgEDA9BQMGgcEwvJgYM5MjsKCgbHEEhoGjgngAynAAEwAOgA7ABqfT8fpeHwcGjjULo5XkuIKFoGQQ6Qna9y6o5jM5ogrKjYmM36K43cj057M95KsRofI8vCCzlwEVitgAGjgbAgSElzOY4hQxyZL1kVPZgjYunlcAAbvRwi5JbyISyiHAAdQgcBxLQDNR3DIXrDur0ieIsc76Jj9Ti8QU4j8Cj3WEPCUR9q5+1A4ChJShqGC4ibiswAIS5Bz5mLUJAw65AA)\n\nEl método 2 también se conoce como [Seguros de tipo definidos por el usuario](https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards) y puede ser muy útil para obtener un código legible. Así es como TS mismo refina tipos con `typeof` e `instanceof`.\n\nSi necesitas, en cambio, cadenas de `if...else` o la sentencia `switch`, debería \"simplemente funcionar\", pero busca [Uniones discriminadas](https://www.typescriptlang.org/docs/handbook/advanced-types.html) si necesitas ayuda. (Ve también: [El escrito de Basarat](https://basarat.gitbooks.io/typescript/docs/types/discriminated-unions.html)). Es útil para asignar tipos en `useReducer` o Redux.\n\n## Tipos opcionales\n\nSi un componente tiene una prop opcional, añade un signo de interrogación y asigna durante las desestructuración (o usa defaultProps).\n\n```tsx\nclass MyComponent extends React.Component\u003c{\n  message?: string; // así\n}\u003e {\n  render() {\n    const { message = \"default\" } = this.props;\n    return \u003cdiv\u003e{message}\u003c/div\u003e;\n  }\n}\n```\n\nTambién puedes usar un carácter `!` para asegurar que algo no es undefined, pero no se recomienda.\n\n_Something to add? [File an issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new) with your suggestions!_\n\n## Tipos Enum\n\nLas Enums en TypeScript se convierten por defecto a números. Usualmente querrás usarlas en cambio como _strings_:\n\n```tsx\nexport enum ButtonSizes {\n  default = \"default\",\n  small = \"small\",\n  large = \"large\"\n}\n```\n\nUso:\n\n```tsx\nexport const PrimaryButton = (\n  props: Props \u0026 React.HTMLProps\u003cHTMLButtonElement\u003e\n) =\u003e \u003cButton size={ButtonSizes.default} {...props} /\u003e;\n```\n\nUna alternativa más simple a los enum es simplemente declarar _strings_ como una unión:\n\n```tsx\nexport declare type Position = \"left\" | \"right\" | \"top\" | \"bottom\";\n```\n\nEsto es útil, porque TypeScript lanzará errores cuando escribas mal un _string_ para tus props.\n\n## Aserción de tipo\n\nEn ocasiones que TypeScript no tiene la razón y que el tipo que estás usando es más restringido que lo que cree, o que los tipos de unión necesitan una aserción con un tipo más especifico para trabajar con otras APIs, para ello hazlo con la palabra clave `as`. Esto le dice al razón que tienes la razón.\n\n```tsx\nclass MyComponent extends React.Component\u003c{\n  message: string;\n}\u003e {\n  render() {\n    const { message } = this.props;\n    return (\n      \u003cComponent2 message={message as SpecialMessageType}\u003e{message}\u003c/Component2\u003e\n    );\n  }\n}\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCmATzCTgGU61gUAbAWSQGduUBzJABVa9ALwFuMKMAB2-fAG4KFOTCRRM6egAUcYbnADeFOHBA8+ggFxwpM+XAA+cAK6yAJkkxykH5eQAvirkaBCyUnAAwriQskiyMABMtsjoMAB0AGJRADx6EAYAfHASABRG5pYCSIEAlKUlZaZwuR7AAG5FLWa5ABYAjEVGFrw1gbkA9IPd5L2T7V0UdSFobCi8cBzUMeDhCfBIAB7qnoZpGBm7cQe5JnNVYzZ20nL8AYEl92ZEnhplDW+ZjgYQi8Eqoys9ECpTgMD6wG4GTA+m4AWBcCIMFcUFkcGaDwxuWu+0SSUeULEI2qgjgG0YzFYnBpwlEn2pT1qUxJ8TJswxdXRcGCQSAA)\n\nNota que no puedes hacer aserciones a tu forma a cualquier cosa (básicamente es solo para refinar tipos). Por tanto no es lo mismo que hacer \"casting\" a un tipo.\n\nTambién puedes hacer una aserción de que una propiedad no es null al acceder a ella:\n\n```ts\nelement.parentNode!.removeChild(element) // ! antes del punto\nmyFunction(document.getElementById(dialog.id!)! // ! después de acceder a la propiedad\nlet userID!: string // aserción de asignación definitiva... ten cuidado!\n```\n\nPor supuesto, intenta realmente manejar el caso null en lugar de hacer la aserción. :)\n\n## Simulación de tipos nominales\n\nEl tipado estructural de TS es útil, hasta que es inconveniente. Sin embargo puedes simular el tipado nominal usando [`marca de tipo`](https://basarat.gitbooks.io/typescript/docs/tips/nominalTyping.html):\n\n```ts\ntype OrderID = string \u0026 { readonly brand: unique symbol };\ntype UserID = string \u0026 { readonly brand: unique symbol };\ntype ID = OrderID | UserID;\n```\n\nPodemos crear estos valores con el patrón de objeto acompañante:\n\n```ts\nfunction OrderID(id: string) {\n  return id as OrderID;\n}\nfunction UserID(id: string) {\n  return id as UserID;\n}\n```\n\nAhora TypeScript no permitirá que uses el ID incorrecto en un lugar determinado:\n\n```ts\nfunction queryForUser(id: UserID) {\n  // ...\n}\nqueryForUser(OrderID(\"foobar\")); // Error, Argument of type 'OrderID' is not assignable to parameter of type 'UserID'\n```\n\nEn el futuro podrás uar la palabra clave `unique` para marcar el tipo. [Consulta este PR](https://github.com/microsoft/TypeScript/pull/33038).\n\n## Tipos de intersección\n\nAñadir dos tipos juntos puede ser útil, por ejemplo cuando se supone que tu componente refleje las props de un componente nativo como `button`:\n\n```tsx\nexport interface Props {\n  label: string;\n}\nexport const PrimaryButton = (\n  props: Props \u0026 React.HTMLProps\u003cHTMLButtonElement\u003e // se añaden mis Props junto con las props de button provistas por @types/react\n) =\u003e \u003cButton {...props} /\u003e;\n```\n\nTambién puedes usar tipos de intersección para hacer subconjuntos reutilizables de props para componentes similares:\n\n```tsx\ntype BaseProps = {\n   className?: string,\n   style?: React.CSSProperties\n   name: string // used in both\n}\ntype DogProps = {\n  tailsCount: number\n}\ntype HumanProps = {\n  handsCount: number\n}\nexport const Human: React.FC\u003cBaseProps \u0026 HumanProps\u003e = // ...\nexport const Dog: React.FC\u003cBaseProps \u0026 DogProps\u003e = // ...\n```\n\n[Ver en TypeScript Playground](https://www.typescriptlang.org/play/?jsx=2#code/JYWwDg9gTgLgBAJQKYEMDG8BmUIjgcilQ3wFgAoCmATzCTgCEUBnJABRzGbgF44BvCnGFoANi2YA5FCCQB+AFxxmMKMAB2AcwA0Q4Suqj5S5OhgA6AMIBlaxwh1YwJMz1x1MpEpVqtcAPT+cACurAAmcBpwAEYQMAAWFAC+VLT0ACIQmvZcvAJ6MCjAosyWEMHqMErqwSDRSFDJqXRwABK1KOo53HyC5MLxnWGl5ZXVtfWN5CnkSAAekLBwaBDqKm0d6ibEFgBilgA8TKzdcABkGyCd3QB8eQAUAJS8d-d6B2HAAG4BNxSPFAo80W8BWa3gmU02zM5n2RxY7E43AukNuD2ePFe70+P38f3IjyAA)\n\nAsegúrate de no confundir los tipos de intersección (que son operaciones **y**) con los tipos de unión (que son operaciones **o**).\n\n## Tipos de unión\n\nEsta sección aún no se ha escrito. (¡Por favor contribuye!). Mientras tanto, consulta nuestro [comentario sobre los casos de uso de los tipos de unión](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/blob/master/README.md#union-types-and-type-guarding).\n\nLa cheatsheet AVANZADA también tiene información sobre los tipos discriminados de unión, que son útiles cuando TypeScript no parece estar reduciendo tu tipo de unión como esperas.\n\n## Sobrecarga de tipos de función\n\nEspecíficamente en lo concerniente a las funciones, puede que necesites sobreescribir en lugar de hacer una unión de tipos. La forma más común en que se escriben los tipos de función es la forma abreviada:\n\n```ts\ntype FunctionType1 = (x: string, y: number) =\u003e number;\n```\n\nPero esto no te permite hacer niguna sobrecarga. Si tienes la implementación, puedes poner los tipos detrás de cada elemento con la palabra clave `function`:\n\n```ts\nfunction pickCard(x: { suit: string; card: number }[]): number;\nfunction pickCard(x: number): { suit: string; card: number };\nfunction pickCard(x): any {\n  // implementation with combined signature\n  // ...\n}\n```\n\nSin embargo, si no tienes ninguna implementación y solo estás escribiendo un archivo de definición `d.ts`, esto tampoco ayudará. En este caso puedes renunciar a las formas abreviadas y escribirlo a la antigua. La clave es recordar que en lo que concierne a TypeScript, `las funciones son solo objetos invocables sin llaves`:\n\n```ts\ntype pickCard = {\n  (x: { suit: string; card: number }[]): number;\n  (x: number): { suit: string; card: number };\n  // no hay necesidad de una firma combinada en esta forma\n  // también puedes añadir tipos a las propiedades estáticas de funciones aquí ej. `pickCard.wasCalled`\n};\n```\n\nNota que cuando implementes la función sobrecargada en sí, la implementación necesitará declarar la firma combinada de la llamada que estás manejando, no lo inferirá por ti. Puedes ver ejemplos fácilmente de sobrecargas en las APIs del DOM, p. ej. `createElement`.\n\n[Lee más sobre la sobrecarga en el manual.](https://www.typescriptlang.org/docs/handbook/functions.html#overloads)\n\n## Uso de tipos inferidos\n\nApoyarse en la inferencia de tipos de TypeScript es genial... hasta que te das cuenta de que necesiotas un tipo que fue inferido, y tienes que volver y declarar explícitamente los tipos o interfaces y así puedas exportarlos para su reutilización.\n\nAfortunadamente, con `typeof`, no tienes que hacerlo. Simplemente úsalo sobre cualquier valor:\n\n```tsx\nconst [state, setState] = React.useState({\n  foo: 1,\n  bar: 2\n}); // el tipo state se infirió como {foo: number, bar: number}\n\nconst someMethod = (obj: typeof state) =\u003e {\n  // obteniendo el tipo del estado aún cuando fue inferido\n  // algún código usando obj\n  setState(obj); // funciona\n};\n```\n\n## Uso de tipos parciales\n\nTrabajar con porciones del estado o las props es común en React. Nuevamente, no necesitas realmente ir y redefinir explícitamente tus tipos si utilizas el tipo genérico `Partial`:\n\n```tsx\nconst [state, setState] = React.useState({\n  foo: 1,\n  bar: 2\n}); // el tipo inferido de state es {foo: number, bar: number}\n\n// NOTA: La mezcla de estado anterior en realidad no se recomienda con React.useState\n// aquí solo estamos demostrando como usar Partial\nconst partialStateUpdate = (obj: Partial\u003ctypeof state\u003e) =\u003e\n  setState({ ...state, ...obj });\n\n// luego...\npartialStateUpdate({ foo: 2 }); // funciona\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003e\n    Advertencias menores al usar \u003ccode\u003ePartial\u003c/code\u003e\n  \u003c/summary\u003e\n\nNota que hay algunos usuarios de TS que no están de acuerdo con usar `Partial` como se comporta hoy. Mira [sútiles problemas del ejemplo anterior aquí](https://twitter.com/ferdaber/status/1084798596027957248), y consulta este largo debate sobre [por qué @types/react usa Pick en lugar de Partial](https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365).\n\n\u003c/details\u003e\n\n## ¡Los tipos que necesito no fueron exportados!\n\nEsto puede ser molesto, ¡pero hay forma de obtener los tipos!\n\n- Obtener los tipos de las props de un componente: `React.ComponentProps` y `typeof`, y opcionalemente `Omit` para omitir cualquier tipo solapado.\n\n```tsx\nimport { Button } from \"library\"; // ¡Pero no exporta ButtonProps! ¡Ay, no!\ntype ButtonProps = React.ComponentProps\u003ctypeof Button\u003e; // !No hay problema! ¡Obtén el tuyo propio!\ntype AlertButtonProps = Omit\u003cButtonProps, \"onClick\"\u003e; // modifícalo\nconst AlertButton: React.FC\u003cAlertButtonProps\u003e = props =\u003e (\n  \u003cButton onClick={() =\u003e alert(\"hello\")} {...props} /\u003e\n);\n```\n\nTambién puedes usar [`ComponentPropsWithoutRef`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a05cc538a42243c632f054e42eab483ebf1560ab/types/react/index.d.ts#L774) (en lugar de ComponentProps) y [`ComponentPropsWithRef`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/a05cc538a42243c632f054e42eab483ebf1560ab/types/react/index.d.ts#L770) (si tu componente específicamente pasa las refs)\n\n- Obtener el tipo de retorno de una función: utiliza `ReturnType`:\n\n```tsx\n// dentro de alguna biblioteca - el tipo de retorno { baz: number } se infiere, pero no se exporta\nfunction foo(bar: string) {\n  return { baz: 1 };\n}\n\n//  dentro de tu aplicación, si necesitas { baz: number }\ntype FooReturn = ReturnType\u003ctypeof foo\u003e; // { baz: number }\n```\n\nDe hecho, puedes obtener virtualmente cualquier cosa que sea pública: [mira esta publicación de Ivan Koshelev](http://ikoshelev.azurewebsites.net/search/id/11/Pragmatic-uses-of-TypeScript-type-system-My-type-of-type)\n\n```ts\nfunction foo() {\n  return {\n    a: 1,\n    b: 2,\n    subInstArr: [\n      {\n        c: 3,\n        d: 4\n      }\n    ]\n  };\n}\n\ntype InstType = ReturnType\u003ctypeof foo\u003e;\ntype SubInstArr = InstType[\"subInstArr\"];\ntype SubIsntType = SubInstArr[0];\n\nlet baz: SubIsntType = {\n  c: 5,\n  d: 6 // ¡Se chequea correctamente el tipo!\n};\n\n// Podrías escribirlo en una sola línea,\n// pero por favor asegúrate de que sea legible hacia adelante\n// (lo puedes entender al leerlo una vez de izquierda a derecha sin saltos)\ntype SubIsntType2 = ReturnType\u003ctypeof foo\u003e[\"subInstArr\"][0];\nlet baz2: SubIsntType2 = {\n  c: 5,\n  d: 6 // ¡Se chequea correctamente el tipo!\n};\n```\n\n# Manual de resolución de problemas: Imágenes y otros archivos que no son TS/TSX\n\nUtiliza [mezcla de declaraciones](https://www.typescriptlang.org/docs/handbook/declaration-merging.html):\n\n```ts\n// declaration.d.ts\n// en cualquier lugar de tu proyecto, NO el mismo nombre de cualquiera de tus archivos .ts/tsx\ndeclare module \"*.png\";\n\n// importación en un archivo tsx\nimport * as logo from \"./logo.png\";\n```\n\nNota que `tsc` no puede empaquetar estos archivos por ti, tendrás que usar Webpack o Parcel.\n\nIssue relacionado: https://github.com/Microsoft/TypeScript-React-Starter/issues/12 y [StackOverflow](https://stackoverflow.com/a/49715468/4216035)\n\n# Manual de resolución de problemas: Operadores\n\n- `typeof` y `instanceof`: consulta de tipos usadas para refinar\n- `keyof`: obtiene llaves de un objeto\n- `O[K]`: búsqueda de una propiedad\n- `[K in O]`: tipos mapeados\n- `+` o `-` o `readonly` o `?`: modificadores de adición, substracción, solo lectura y opcionalidad\n- `x ? Y : Z`: Tipos condicionales para tipos genéricos, alias de tipo y tipos de parámetros de función\n- `!`: Aserción de no nulidad para tipos que pueden ser nulos\n- `=`: Valor por defecto del tipo paramétrico genérico en tipos genéricos\n- `as`: aserción de tipo\n- `is`: protección de tipo para tipos de retorno de funciones\n\nLos tipos condicionales son un tema difícil de comprender, por lo que aquí hay algunos recursos extra:\n\n- Explicación completa paso a paso https://artsy.github.io/blog/2018/11/21/conditional-types-in-typescript/\n- _Bail out_ y otros temas avanzados https://github.com/sw-yx/ts-spec/blob/master/conditional-types.md\n\n# Manual de resolución de problemas: Utilitarios\n\nTodos estos están incorporados, [mira el código en es5.d.ts](https://github.com/microsoft/TypeScript/blob/2c458c0d1ccb96442bca9ce43aa987fb0becf8a9/src/lib/es5.d.ts#L1401-L1474):\n\n- `ConstructorParameters`: una tupla de los tipos de los parámetros del constructor\n- `Exclude`: excluye un tipo de otro tipo\n- `Extract`: selecciona un subtipo que es asignable a otro tipo\n- `InstanceType`: el tipo de instancia que obtienes al hacer `new` a `new` a un constructor de clase\n- `NonNullable`: excluye `null` y `undefined` de un tipo\n- `Parameters`: una tupla de los tipos de los parámetros de una función\n- `Partial`: Hace que todas las propiedades en un objeto sean opcionales\n- `Readonly`: Hace que todas las propiedades en un objeto sean de solo lectura\n- `ReadonlyArray`: Hace un arreglo inmutable del tipo dado\n- `Pick`: Un subtipo de un tipo de objeto con un subconjunto de sus llaves\n- `Record`: Un mapeo de un tipo de llave a un tipo de valor\n- `Required`: Hace todas que todas las propiedades de un objeto sean requeridas\n- `ReturnType` El tipo de retorno de una función\n\n# Manual de resolución de problemas: ESLint\n\n**Nota: TSLint está en modo de mantenimiento y ESLint es el camino a seguir para TypeScript. [Puedes convertir TSlint a ESlint con esta herramienta](https://github.com/typescript-eslint/tslint-to-eslint-config).**\n\nEsta sección necesita escribirse, pero probablemente puedes encontrar un buen punto para comenzar en la [configuración de ESLint de Wes Bos](https://github.com/wesbos/eslint-config-wesbos) (que viene con una [introducción en YouTube](https://www.youtube.com/watch?v=lHAeK8t94as)).\n\n¡Luego, revisa las secciones sobre [Prettier](/AVANZADO.md#prettier) y [Linting](/AVANZADO.md#linting) cheatsheet AVANZADA!\n\n# Manual de resolución de problemas: tsconfig.json\n\nPuedes encontrar [todas las opciones del compilador en la documentación de TypeScript](https://www.typescriptlang.org/docs/handbook/compiler-options.html). Esta es la configuración que utilizo en APLICACIONES (no para bibliotecas; para bibliotecas puede que quieras ver las configuraciones que usamos en `tsdx`):\n\n```json\n{\n  \"compilerOptions\": {\n    \"incremental\": true,\n    \"outDir\": \"build/lib\",\n    \"target\": \"es5\",\n    \"module\": \"esnext\",\n    \"lib\": [\"dom\", \"esnext\"],\n    \"sourceMap\": true,\n    \"importHelpers\": true,\n    \"declaration\": true,\n    \"rootDir\": \"src\",\n    \"strict\": true,\n    \"noUnusedLocals\": true,\n    \"noUnusedParameters\": true,\n    \"noImplicitReturns\": true,\n    \"noFallthroughCasesInSwitch\": true,\n    \"allowJs\": false,\n    \"jsx\": \"react\",\n    \"moduleResolution\": \"node\",\n    \"baseUrl\": \"src\",\n    \"forceConsistentCasingInFileNames\": true,\n    \"esModuleInterop\": true,\n    \"suppressImplicitAnyIndexErrors\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"experimentalDecorators\": true\n  },\n  \"include\": [\"src/**/*\"],\n  \"exclude\": [\"node_modules\", \"build\", \"scripts\"]\n}\n```\n\nPor favor abre un issue y expresa tu opinión sobre si existen mejores elecciones a recomendar para React.\n\nBanderas seleccionadas y por qué nos gustan:\n\n- `esModuleInterop`: deshabilita imports de espacios de nombre (`import * as foo from \"foo\"`) y habilita imports al estilo de CJS/AMD/UMD (`import fs from \"fs\"`)\n- `strict`: `strictPropertyInitialization` te obliga a inicializar las propiedades de clase o declarar explícitamente que pueden no estar definidas. Puedes evitarlo usando una aserción de asignación definitiva.\n- `\"typeRoots\": [\"./typings\", \"./node_modules/@types\"]`: Por defecto, TypeScript busca en `node_modules/@types` y directorios ancestros para buscar declaraciones de tipos de terceros. Podrías querer sobreescribir esta resolución por defecto de manera tal de que pudieras poner todas tus declaraciones globales de tipos en un directorio especial `typings`.\n\nLa velocidad de la compilación crece linealmente con el tamaño de la base de código. Para proyectos grandes, querrás usar [Referencias de proyecto](https://www.typescriptlang.org/docs/handbook/project-references.html). Mira nuestra cheatsheet [AVANZADA](AVANZADO.md) para comentarios.\n\n# Manual de resolución de problemas: Errores en tipos oficiales\n\nSi te encuentras errores en los tipos de tu biblioteca oficial, puedes copiarlos localmente y decirle a TypeScript que utilice tu versión local usando el campo \"paths\". En tu `tsconfig.json`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"paths\": {\n      \"mobx-react\": [\"../typings/modules/mobx-react\"]\n    }\n  }\n}\n```\n\n[Gracias a @adamrackis for el consejo.](https://twitter.com/AdamRackis/status/1024827730452520963)\n\nSi solo quieres añadir una interfaz, o añadir miembros que faltan a una interfaz existente, no necesitas copiar todo el paquete de tipos. En cambio, puedes utilizar la [mezcla de declaraciones](https://www.typescriptlang.org/docs/handbook/declaration-merging.html):\n\n```tsx\n// my-typings.ts\ndeclare module \"plotly.js\" {\n  interface PlotlyHTMLElement {\n    removeAllListeners(): void;\n  }\n}\n\n// MyComponent.tsx\nimport { PlotlyHTMLElement } from \"plotly.js\";\n\nconst f = (e: PlotlyHTMLElement) =\u003e {\n  e.removeAllListeners();\n};\n```\n\nNo siempre tienes que implementar el módulo, puedes simplementer importar el módulo como `any` para un inicio rápido:\n\n```tsx\n// my-typings.ts\ndeclare module \"plotly.js\"; // cada uno de estas importaciones son `any`\n```\n\nDado que no tienes que explícitamente exportarlo, se conoce como [declaración de módulo de ambiente](https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html#pitfalls-of-namespaces-and-modules). puedes hacer una declaración de módulo de ambiente en un archivo `.ts` en modo de script (sin imports o exports), o en un archivo `.d.ts` en cualquier lugar de tu proyecto.\n\nTambién puedes hacer declaraciones de variables de ambiente y de tipos de ambiente:\n\n```ts\n// tipo utilitario de ambiente\ntype ToArray\u003cT\u003e = T extends unknown[] ? T : T[];\n// variable de ambiente\ndeclare let process: {\n  env: {\n    NODE_ENV: \"development\" | \"production\";\n  };\n};\nprocess = {\n  env: {\n    NODE_ENV: \"production\"\n  }\n};\n```\n\nTambién puedes ver ejemplos de ellos en las declaraciones de tipos incorporadas en el campo `lib` de `tsconfig.json`\n\n# Bases de código de React + TypeScript recomendadas para aprender\n\n- https://github.com/jaredpalmer/formik\n- https://github.com/jaredpalmer/react-fns\n- https://github.com/palantir/blueprint\n- https://github.com/Shopify/polaris\n- https://github.com/NullVoxPopuli/react-vs-ember/tree/master/testing/react\n- https://github.com/artsy/reaction\n- https://github.com/benawad/codeponder (¡con [programación en vivo!](https://www.youtube.com/watch?v=D8IJOwdNSkc\u0026list=PLN3n1USn4xlnI6kwzI8WrNgSdG4Z6daCq))\n- https://github.com/artsy/emission (React Native)\n- [@reach/ui's community typings](https://github.com/reach/reach-ui/pull/105)\n\n_Boilerplates_ de React:\n\n- [@jpavon/react-scripts-ts](https://github.com/jpavon/react-scripts-ts) react-scripts alternativos con todas las funcionalidades de TypeScript usando [ts-loader](https://github.com/TypeStrong/ts-loader)\n- [webpack config tool](https://webpack.jakoblind.no/) es una herramienta visual para la cración de proyectos de webpack con React y TypeScript\n- \u003chttps://github.com/innFactory/create-react-app-material-typescript-redux\u003e plantilla lista para usarse con [Material-UI](https://material-ui.com/), enrutamiento y Redux\n\n_Boilerplates_ de React Native: _contribución de [@spoeck](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/pull/20)_\n\n- https://github.com/GeekyAnts/react-native-seed\n- https://github.com/lopezjurip/ReactNativeTS\n- https://github.com/emin93/react-native-template-typescript\n- \u003chttps://github.com/Microsoft/TypeScript-React-Native-Starter\u003e\n\n# Herramientas e integración en editores\n\n- VSCode\n  - Extensión de VSCode de swyx: https://github.com/sw-yx/swyx-react-typescript-snippets\n  - amVim: https://marketplace.visualstudio.com/items?itemName=auiworks.amvim\n- VIM\n  - https://github.com/Quramy/tsuquyomi\n  - ¿nvim-typescript?\n  - https://github.com/leafgarland/typescript-vim\n  - peitalin/vim-jsx-typescript\n  - NeoVim: https://github.com/neoclide/coc.nvim\n  - otros discusiones: https://mobile.twitter.com/ryanflorence/status/1085715595994095620\n\n## Linting\n\n\u003e ⚠️ Nota que [TSLint ahora está en mantenimiento y deberías intentar usar ESLint en su lugar](https://medium.com/palantir/tslint-in-2019-1a144c2317a9). Si está interesado en los consejos de TSLint, consulte este PR desde [@azdanov](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/pull/14). El resto de esta sección solo se centra en ESLint.\n\n\u003e ⚠️ Este es un tema en evolución. `typescript-eslint-parser` ya no se mantiene y [el trabajo ha comenzado recientemente sobre`typescript-eslint` en la comunidad ESLint](https://eslint.org/blog/2019/01/future-typescript-eslint) para lleve ESLint con TSLint.\n\nSiga los documentos de TypeScript + ESLint en https://github.com/typescript-eslint/typescript-eslint:\n\n```\nyarn add -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint\n```\n\nagregue un script `lint` a su`package.json`:\n\n```json\n  \"scripts\": {\n    \"lint\": \"eslint 'src/**/*.ts'\"\n  },\n```\n\ny en `.eslintrc.json` adecuado:\n\n```json\n{\n  \"env\": {\n    \"es6\": true,\n    \"node\": true,\n    \"jest\": true\n  },\n  \"extends\": \"eslint:recommended\",\n  \"parser\": \"@typescript-eslint/parser\",\n  \"plugins\": [\"@typescript-eslint\"],\n  \"parserOptions\": {\n    \"ecmaVersion\": 2017,\n    \"sourceType\": \"module\"\n  },\n  \"rules\": {\n    \"indent\": [\"error\", 2],\n    \"linebreak-style\": [\"error\", \"unix\"],\n    \"quotes\": [\"error\", \"single\"],\n    \"no-console\": \"warn\",\n    \"no-unused-vars\": \"off\",\n    \"@typescript-eslint/no-unused-vars\": [\n      \"error\",\n      { \"vars\": \"all\", \"args\": \"after-used\", \"ignoreRestSiblings\": false }\n    ],\n    \"no-empty\": \"warn\"\n  }\n}\n```\n\nEsto está tomado de [el `tsdx` PR](https://github.com/palmerhq/tsdx/pull/70/files) que es para **bibliotecas**.\n\nMás opciones de `.eslintrc.json` se pueden desear para **aplicaciones**:\n\n```json\n{\n  \"extends\": [\n    \"airbnb\",\n    \"prettier\",\n    \"prettier/react\",\n    \"plugin:prettier/recommended\",\n    \"plugin:jest/recommended\",\n    \"plugin:unicorn/recommended\"\n  ],\n  \"plugins\": [\"prettier\", \"jest\", \"unicorn\"],\n  \"parserOptions\": {\n    \"sourceType\": \"module\",\n    \"ecmaFeatures\": {\n      \"jsx\": true\n    }\n  },\n  \"env\": {\n    \"es6\": true,\n    \"browser\": true,\n    \"jest\": true\n  },\n  \"settings\": {\n    \"import/resolver\": {\n      \"node\": {\n        \"extensions\": [\".js\", \".jsx\", \".ts\", \".tsx\"]\n      }\n    }\n  },\n  \"overrides\": [\n    {\n      \"files\": [\"**/*.ts\", \"**/*.tsx\"],\n      \"parser\": \"typescript-eslint-parser\",\n      \"rules\": {\n        \"no-undef\": \"off\"\n      }\n    }\n  ]\n}\n```\n\nPuede leer una [guía de configuración más completa de TypeScript + ESLint aquí](https://blog.matterhorn.dev/posts/learn-typescript-linting-part-1/) de Matterhorn, en particular consulte https://github.com/MatterhornDev/learn-typescript-linting.\n\nSi está buscando información sobre Prettier, consulte [Prettier](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/blob/master/ADVANCED.md#prettier).\n\n# Otros recursos sobre React + TypeScript\n\n- !Yo! \u003chttps://twitter.com/swyx\u003e\n- \u003chttps://github.com/piotrwitek/react-redux-typescript-guide\u003e - **MUY MUY RECOMENDADO**, escribí este repo antes de conocer sobre este, este tien muchas cosas que no cubro, incluyendo **REDUX** y **JEST**.\n- [Ultimate React Component Patterns with TypeScript 2.8](https://levelup.gitconnected.com/ultimate-react-component-patterns-with-typescript-2-8-82990c516935)\n- [Basarat's TypeScript gitbook has a React section](https://basarat.gitbooks.io/typescript/content/docs/jsx/react.html) con un [curso de Egghead.io](https://egghead.io/courses/use-typescript-to-develop-react-applications) también.\n- [Palmer Group's Typescript + React Guidelines](https://github.com/palmerhq/typescript) así como también otros trabajos de Jared como [disco.chat](https://github.com/jaredpalmer/disco.chat)\n- [Sindre Sorhus' TypeScript Style Guide](https://github.com/sindresorhus/typescript-definition-style-guide)\n- [TypeScript React Starter Template by Microsoft](https://github.com/Microsoft/TypeScript-React-Starter) Una plantilla de inicio para TypeScript y React con un README detallado donde se describe cómo usarlos juntos. Nota: esto parece ya no actualizarse frecuentemente.\n- [Curso intermedio sobre React de Brian Holt en Frontend Masters (de pago)](https://frontendmasters.com/courses/intermediate-react/converting-the-app-to-typescript/) - Sección sobre convertir una aplicación a TypeScript\n- Conversión a TypeScript:\n  - [CLI de conversión de React a TypeScript de Lyft](https://github.com/lyft/react-javascript-to-typescript-transform)\n  - [Publicación de Gustav Wengel - Conversión de una base de código en React a TypeScript](http://www.gustavwengel.dk/converting-typescript-to-javascript-part-1)\n  - [Guía de conversión de React a Typescript de Microsoft](https://github.com/Microsoft/TypeScript-React-Conversion-Guide#typescript-react-conversion-guide)\n- [¿Tú?](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n# Charlas recomendadas sobre React + TypeScript\n\n- ¡Por favor ayuda a contribuir con esta nueva sección!\n\n# Hora de realmente aprender TypeScript\n\nLo creas o no, apenas hemos introducido TypeScript en esta cheatsheet. Hay un mundo complejo de loǵica de tipos genéricos al que eventualmente te enfrentarás, sin embargo se trata menos de lidiar con React que simplemente mejorar en TypeScript, y por eso está fuera de este ámbito. Pero al menos ahora ya puedes ser productivo en React :)\n\nVale la pena menicionar algunos recursos para inciarse:\n\n- La sección de los 40+ ejemplos [del playground](http://www.typescriptlang.org/play/index.html), escrito por @Orta\n- El resumen de TS de Anders Hejlsberg's: https://www.youtube.com/watch?v=ET4kT88JRXs\n- Marius Schultz: https://blog.mariusschulz.com/series/typescript-evolution con un [curso de Egghead.io](https://egghead.io/courses/advanced-static-types-in-typescript)\n- La explicación profunda de Basarat: https://basarat.gitbooks.io/typescript/\n- Rares Matei: [El curso de Egghead.io](https://egghead.io/courses/practical-advanced-typescript) Advanced Typescript es muy bueno para las funcionalidades más nuevas de TypeScript y aplicaciones prácticas de la lógica de tipos (p. ej. hacer recursivamente todas las propiedades de un tipo como `readonly`).\n\n# Aplicación de ejemplo\n\n- [React TypeScript Todo Example 2019 Mid](https://github.com/ryota-murakami/react-typescript-todo-example-2019)\n\n# ¡Mi pregunta no está respondida aquí!\n\n- Consulta la [cheatsheet avanzada](/AVANZADO.md)\n- [Abre un issue](https://github.com/typescript-cheatsheets/react-typescript-cheatsheet/issues/new).\n\n## Contribuidores\n\nEste proyecto sigue la especificación de [all-contributors](https://github.com/all-contributors/all-contributors). Mira [CONTRIBUTORS.md](/CONTRIBUTORS.md) para la lista completa. ¡Contribuciones de cualquier tipo son bienvenidas!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypescript-cheatsheets%2Freact-typescript-cheatsheet-es","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftypescript-cheatsheets%2Freact-typescript-cheatsheet-es","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftypescript-cheatsheets%2Freact-typescript-cheatsheet-es/lists"}