Cristian Mora
Cortaron la clase o es mi impresión?
Aprender a tipar useReducer y Context API con TypeScript te ayuda a prevenir errores, mejorar la legibilidad de tu código y hacer debugging más rápido en proyectos React. Si ya trabajas con estos hooks en JavaScript, este recorrido te muestra cómo darles tipos precisos para que tu editor te avise antes de romper algo.
¿Cómo se tipa useReducer en React con TypeScript?
Un useReducer tiene dos piezas que necesitas tipar: el estado y las acciones. Si tu reducer accede a state.count, ya sabes que el estado es un objeto, y si accede a action.type, la acción también lo es.
¿Cómo defino el tipo del estado?
En el ejemplo del contador, el estado tiene una propiedad count que guarda un número. La definición queda así [0:34]:
ts type State = { count: number; };
Con eso le dices a TypeScript que cualquier estado que pase por tu reducer debe ser un objeto con count numérico. Nada más, nada menos.
¿Cómo defino el tipo de las acciones?
Aquí viene lo interesante. Dentro del switch del reducer solo existen dos acciones válidas: increment y decrement. En vez de tipar type como un string genérico, puedes restringirlo a esos dos valores literales [1:05]:
ts type Action = { type: 'increment' | 'decrement'; };
Esto se llama union de literales y es una de las herramientas más potentes de TypeScript. Si por error escribes incremennt con una n de más, el editor te marca el problema antes de ejecutar el código.
¿Por qué usar literales en lugar de string? Porque garantizan que solo lleguen los valores válidos. Si tipas como
string, un typo pasa desapercibido y rompe tu reducer en tiempo de ejecución.
¿Cómo tipar la firma del reducer?
Un reducer recibe un estado y una acción, y devuelve un nuevo estado. Esa entrada y salida también se tipa [1:48]:
ts function reducer(state: State, action: Action): State { switch (action.type) { case 'increment': return { count: state.count + 1 }; case 'decrement': return { count: state.count - 1 }; } }
Los dos puntos después de los paréntesis indican el tipo de retorno. Si tu reducer devuelve algo que no encaja con State, TypeScript lo detecta al instante. Esa retroalimentación inmediata es la que ahorra horas de debugging.
¿Cómo se tipa Context API en React?
El segundo ejercicio es un contexto para cambiar el tema de un botón entre claro y oscuro. El contexto expone dos cosas: el valor del tema y una función toggleTheme que lo cambia.
¿Cómo defino el tipo del contexto?
Una buena convención es nombrar el tipo igual que el contexto, agregando la palabra Type al final. Así mantienes consistencia en todo el proyecto [3:10]:
ts type ThemeContextType = { theme: string; toggleTheme: () => void; };
El tema es un string (puede ser light o dark) y toggleTheme es una función que no retorna nada, por eso usas () => void. Ese void indica explícitamente que no esperas un valor de regreso.
¿Cómo paso ese tipo a createContext?
Usas picoparéntesis (los símbolos <>) para indicar el tipo genérico:
ts const ThemeContext = createContext<ThemeContextType>(/* valor inicial */);
Con eso, cualquier componente que consuma el contexto sabe exactamente qué propiedades existen y de qué tipo son.
¿Cómo tipar children en el Provider?
El provider recibe children, que en React es cualquier cosa renderizable: un elemento, un texto, varios componentes anidados. El tipo correcto es ReactNode [4:25]:
ts type ProviderProps = { children: React.ReactNode; };
function ThemeProvider({ children }: ProviderProps): React.ReactNode { // lógica }
También puedes anotar el tipo de retorno del componente como ReactNode para dejar claro qué devuelve.
¿Qué es ReactNode? Es el tipo que cubre todo lo que React puede renderizar: elementos JSX, strings, números, arrays o fragments. Es la opción más flexible para tipar
children.
¿Por qué vale la pena tipar en proyectos React?
En componentes pequeños el tipado parece innecesario, pero en proyectos grandes se vuelve una herramienta gigantesca. Estos son los beneficios concretos:
La coerción de tipos es ese comportamiento de JavaScript que convierte automáticamente entre strings, números y booleanos cuando los mezclas. Cuando estudias JavaScript suena intuitivo, pero en producción esos casos raros te explotan en la cara. TypeScript te quita ese problema de encima.
Cuéntame en los comentarios qué tal te pareció este módulo sobre TypeScript.
Cristian Mora
Cortaron la clase o es mi impresión?
Max Andy Diaz Neyra
Fernando Labastida Vázquez
Todo mal con esta clase xd
Johan Sebastian
No se explica bien, y deja a medias lo explicado
Samuel Schulz
ContextApi.tsx
import { useContext, createContext, useState } from "react";
type ThemeContextType = {
theme: string; /* theme: "light" | "dark"; */
toggleTheme: () => void;
};
const ThemeContext = createContext<ThemeContextType>({} as ThemeContextType);
function ThemeProvider({ children }: { children: React.ReactNode }): React.ReactNode {
const [theme, setTheme] = useState<ThemeContextType["theme"]>("light");
const toggleTheme = () => {
setTheme((prevTheme) => (prevTheme === "light" ? "dark" : "light"));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
function ThemeButton() {
const { theme, toggleTheme } = useContext(ThemeContext);
return (
<button
onClick={toggleTheme}
style={theme === "light" ? { background: "#fff", color: "#000" } : { background: "#333", color: "#fff" }}
>
Cambiar a {theme === "light" ? "dark" : "light"}
</button>
);
}
export { ThemeProvider, ThemeButton };
App.tsx
import Button from "./components/Button";
import Counter from "./components/Counter";
import { ThemeProvider, ThemeButton } from "./components/ContextApi";
import "./App.css";
// function greet(name: string): string {
// return `Hello, ${name}!`;
// }
function App() {
const handleClick = () => {
alert("Button clicked!");
};
// console.log(greet("Sam"));
return (
<div className="App">
<Button onClick={handleClick} label="Click me" />
<br />
<br />
<Counter />
<br />
<br />
<ThemeProvider>
<ThemeButton />
</ThemeProvider>
</div>
);
}
export default App;
Alfonso Neil Jiménez Casallas
hay que corregir un pequeño detalle en el repositorio curso-react/my-react-app-with-ts/src/components/ContextApi.tsx at main · platzi/curso-react
// Definimos el tipo del contexto type ThemeContextType = { theme: "light" | "dark"; toggleTheme: () => void; }; ```// Definimos el tipo del contexto type ThemeContextType = {   theme: "light" | "dark";   toggleTheme: () => void; };
Sofia Libertad Montoya Herrera
Me gustaría compartir un video que también hace uso del hook 'useReducer' completamente tipado. Espero que les sirva para profundizar un poco más.
German Ortegon
Esta clase me esta solicitando respoder un ejercicio, Completa el tipado del reducer con TypeScript, pero el ejercio esta mal y no me deja continuar
Gustavo Albornoz
me pasó exactamente lo mismo, por ahora la solucion es "saltarse el reto" moviendose a traves del tiempo del video
Emilio Flor
La coerción es el proceso de conversión de un tipo de dato a otro. Esto puede ocurrir de manera automática (coerción implícita), como cuando JavaScript convierte el número 3 a string para sumarlo a "3", resultando en "33"; o de forma forzada (coerción explícita), que es cuando el desarrollador usa funciones específicas como Number() para realizar la conversión.
TypeScript es un lenguaje con tipado estático que resuelve muchos de los problemas asociados con la coerción implícita de JavaScript. Al exigir la definición de tipos, TypeScript elimina una gran cantidad de errores humanos por suposición u omisiones, permitiéndonos como desarrolladores ahorrar tiempo a largo plazo.
En contraste, JavaScript, al ser un lenguaje de tipado dinámico, a menudo intenta interpretar lo que el desarrollador asume, lo que lleva a comportamientos inesperados y a los llamados "errores coertivos".
El ejemplo de sumar "3" con 3 y obtener "33" es un claro síntoma de esta dinámica. Además, la ausencia de un sistema de tipos estático significa que el lenguaje no puede avisarte si cometes un simple error de escritura, como escribir incrementt en lugar de increment, errores que pueden ser increíblemente frustrantes y consumir horas de depuración.
josorioc
Me parecio que no fue muy claro su uso..si alguno tiene alguna documentación adicional os agreceria.
Martin Lazzeri
Soy Team lenguajes tipados
Luis Eduardo Payano Villar
State: shape exacta del estado Action: discriminated union (clave para DX y seguridad) Reducer: (state, action) => newState Context Value: { state, dispatch } o acciones “helper” ya tipadas Hook useX() que valida que el Provider existe
Luis Eduardo, the question describes key elements for typing useReducer and Context API in TypeScript.
dispatch function, or typed "helper" actions.useX(): A custom hook that validates the existence of the Provider before use.This approach helps prevent runtime errors and improves code maintainability.
Alvaro Rafael Guete Puello
¿Cómo afecta el uso de tipos genéricos en la reutilización de componentes en React con TypeScript?
Daniel Alberto Vega Bejarano
Importante para manejar coherencia en el código, al igual que lo hacen otros lenguajes, como por ejemplo c#
Genial el use de TypeScrip, aqui les dejo el codigo del ultimo ejemplo:
import { createContext, useState, type ReactNode } from "react"; type ThemeContextType = { theme: "light" | "dark"; toggleTheme: () => void; }; const ThemeContext = createContext<ThemeContextType>({} as ThemeContextType); function ThemeProvider({ children }: { children: ReactNode }) { const [theme, setTheme] = useState<ThemeContextType["theme"]>("light"); const toggleTheme = () => { setTheme((prev) => (prev === "light" ? "dark" : "light")); }; return ( <ThemeContext.Provider value={{ theme, toggleTheme }}> {children} </ThemeContext.Provider> ); } export { ThemeContext, ThemeProvider };