TypeScript con React: genéricos, FC y hooks
Tipifique componentes de React con props genéricas, anote useState y useRef con tipos explícitos y tipifique hooks personalizados que devuelvan tuplas.
TypeScript con React: genéricos, FC y hooks es una lección gratuita de Frontend Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Frontend Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Frontend Academy incluye 4 lecciones en total.
Tipado de componentes
React moderno: defina el tipo de las props con una interfaz y utilice una función convencional. React.FC existe, pero ya no se recomienda (añade children implícitamente y no admite genéricos).
// Recommended:
interface ButtonProps {
label: string;
onClick: () => void;
disabled?: boolean;
}
function Button({ label, onClick, disabled }: ButtonProps) {
return <button onClick={onClick} disabled={disabled}>{label}</button>;
}Tipado de children
Utilice React.ReactNode para cualquier elemento hijo que se pueda renderizar.
interface CardProps {
title: string;
children: React.ReactNode;
}
function Card({ title, children }: CardProps) {
return (
<div className="card">
<h2>{title}</h2>
{children}
</div>
);
}Tipado de useState
useState normalmente infiere el tipo a partir del valor inicial. Proporcione un tipo explícito cuando el valor inicial sea null o no represente todas las posibilidades del tipo.
const [count, setCount] = useState(0); // number
const [name, setName] = useState(''); // string
const [user, setUser] = useState<User | null>(null); // explicit
const [items, setItems] = useState<Item[]>([]); // explicit array typeTipado de useRef
Hay dos formas: una referencia a un elemento del DOM (inicializada con null) o un contenedor mutable.
const inputRef = useRef<HTMLInputElement>(null);
const timerRef = useRef<number | null>(null);
useEffect(() => {
inputRef.current?.focus();
timerRef.current = window.setInterval(tick, 1000);
return () => clearInterval(timerRef.current!);
}, []);Tipado de controladores de eventos
Utilice los tipos de eventos sintéticos de React.
function Form() {
function onSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
}
function onChange(e: React.ChangeEvent<HTMLInputElement>) {
setValue(e.target.value);
}
function onClick(e: React.MouseEvent<HTMLButtonElement>) {
/* ... */
}
return <form onSubmit={onSubmit}>...</form>;
}Componentes genéricos
Los componentes pueden ser genéricos: TypeScript infiere el parámetro de tipo a partir del lugar donde se realiza la llamada.
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
keyOf: (item: T) => string | number;
}
function List<T>({ items, renderItem, keyOf }: ListProps<T>) {
return <ul>{items.map(i => <li key={keyOf(i)}>{renderItem(i)}</li>)}</ul>;
}
<List<User>
items={users}
renderItem={u => u.name}
keyOf={u => u.id}
/>Tipado de hooks personalizados
Los hooks personalizados son funciones; tipifíquelos como cualquier otra función. Las tuplas devueltas necesitan una anotación explícita para evitar que el tipo se amplíe a un array.
function useToggle(initial = false): [boolean, () => void] {
const [value, setValue] = useState(initial);
const toggle = () => setValue(v => !v);
return [value, toggle]; // tuple — annotation makes this stable
}
const [isOpen, toggle] = useToggle();Tipado de Context
createContext necesita un valor inicial del mismo tipo que el valor que proporcionará. Utilice una aserción de no nulidad o un objeto predeterminado.
interface AuthContextValue {
user: User | null;
signIn: (email: string, pw: string) => Promise<void>;
signOut: () => void;
}
const AuthContext = createContext<AuthContextValue | null>(null);
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error('useAuth must be inside AuthProvider');
return ctx;
}Tipado de useReducer
Especifique explícitamente el tipo del estado y la unión de acciones.
type State = { count: number };
type Action =
| { type: 'increment' }
| { type: 'decrement' }
| { type: 'set'; value: number };
function reducer(state: State, action: Action): State {
switch (action.type) {
case 'increment': return { count: state.count + 1 };
case 'decrement': return { count: state.count - 1 };
case 'set': return { count: action.value };
}
}
const [state, dispatch] = useReducer(reducer, { count: 0 });Evitar React.FC
React.FC ha caído en desuso: añade children implícitamente, no admite componentes genéricos de forma adecuada y limita algunas optimizaciones. Prefiera componentes de función convencionales con props tipadas.
Utilidad ComponentPropsWithoutRef
Para heredar las props de un elemento nativo, como al extender un botón o un campo de entrada, utilice ComponentPropsWithoutRef.
type ButtonProps = React.ComponentPropsWithoutRef<'button'> & {
variant?: 'primary' | 'secondary';
};
function Button({ variant = 'primary', ...rest }: ButtonProps) {
return <button className={`btn ${variant}`} {...rest} />;
}Comprobación rápida
¿Por qué se suele desaconsejar usar React.FC en favor de componentes de función tipados directamente?
Repaso: TypeScript + React
Tipifique las props con interfaces y prefiera las funciones normales en lugar de React.FC. children: React.ReactNode. useState suele inferir el tipo; añada una anotación para null y los arrays vacíos. Use useRef para elementos del DOM. Utilice los tipos de eventos de React para los controladores. Use componentes genéricos para listas y formularios reutilizables. La tupla que devuelven los hooks personalizados necesita una anotación. Use ComponentPropsWithoutRef para extender elementos nativos.
Preguntas frecuentes
¿La lección «TypeScript con React: genéricos, FC y hooks» es gratis?
Sí — el texto completo de «TypeScript con React: genéricos, FC y hooks» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Frontend Academy, actualiza a CoddyKit PRO. El curso de Frontend Academy incluye 4 lecciones en total.
¿Qué aprenderé en «TypeScript con React: genéricos, FC y hooks»?
Tipifique componentes de React con props genéricas, anote useState y useRef con tipos explícitos y tipifique hooks personalizados que devuelvan tuplas. Practicas Frontend Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Frontend Academy?
No se requiere experiencia previa. Frontend Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «TypeScript con React: genéricos, FC y hooks»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Frontend Academy?
Sí. Cada lección de Frontend Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Tipos de literales de plantilla
- Decoradores y metadatos
- TypeScript con React: genéricos, FC y hooks
- Modo estricto y eliminación de any