home / skills / hoangnguyen0403 / agent-skills-standard / typescript

typescript skill

/skills/react/typescript

This skill enforces type-safe React TypeScript patterns to improve components, hooks, and event handling with precise typings.

npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill typescript

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
1.3 KB
---
name: React TypeScript
description: TypeScript patterns specific to React components and hooks.
metadata:
  labels: [react, typescript, types]
  triggers:
    files: ['**/*.tsx']
    keywords: [ReactNode, FC, PropsWithChildren, ComponentProps]
---

# React TypeScript

## **Priority: P1 (OPERATIONAL)**

Type-safe React patterns.

## Implementation Guidelines

- **Components**: Return `JSX.Element`. Props interface over `React.FC`.
- **Children**: Use `ReactNode` or `PropsWithChildren<T>`.
- **Events**: `React.ChangeEvent<HTMLInputElement>`.
- **Hooks**: `useRef<HTMLDivElement>(null)`. `useState<User | null>(null)`.
- **Props**: Use `ComponentProps<'button'>` to mirror native els.
- **Generics**: `<T,>(props: ListProps<T>)`.
- **Polymorphism**: `as` prop patterns.

## Anti-Patterns

- **No `any`**: Use `unknown`.
- **No `React.FC`**: Implicit children is deprecated/bad practice.
- **No `Function`**: Use `(args: T) => void`.

## Code

```tsx
// Modern Props
type ButtonProps = ComponentProps<'button'> & {
  variant?: 'primary' | 'secondary';
};

// Generic Component
type ListProps<T> = {
  items: T[];
  render: (item: T) => ReactNode;
};

function List<T>({ items, render }: ListProps<T>) {
  return <ul>{items.map(render)}</ul>;
}

// Hook Ref
const inputRef = useRef<HTMLInputElement>(null);
```

Overview

This skill documents TypeScript patterns tailored for React components and hooks to ensure type safety and maintainability. It highlights recommended types, generics, polymorphism patterns, and common anti-patterns to avoid runtime errors and improve developer experience.

How this skill works

The skill inspects component signatures, prop typing, hook usage, and event types to enforce explicit, safe types. It recommends concrete TypeScript constructs like ComponentProps, ReactNode, and typed refs/useState, and flags unsafe patterns such as use of any, React.FC, and the Function type.

When to use it

  • When building new React components and ensuring props are fully typed.
  • When converting a JavaScript React codebase to TypeScript.
  • When writing reusable generic components (lists, form controls).
  • When creating polymorphic components that accept an as prop.
  • When typing refs, state, and DOM event handlers in hooks and components.

Best practices

  • Return JSX.Element from components and prefer explicit props interfaces over React.FC.
  • Type children with ReactNode or use PropsWithChildren<T> for predictable children handling.
  • Use ComponentProps<'element'> to mirror native element attributes for button/input props.
  • Type DOM events explicitly, e.g., React.ChangeEvent<HTMLInputElement>, and avoid the untyped Event.
  • Prefer unknown over any and always type function signatures as (args: T) => void, not Function.
  • Use generics with a trailing comma syntax: function List<T,>({ items, render }: ListProps<T>) { ... }

Example use cases

  • A typed Button component that extends native button attributes and adds variant props.
  • A generic List<T> component that accepts items of any type and a render function.
  • Forms with controlled inputs using useRef<HTMLInputElement>(null) and typed change handlers.
  • Polymorphic components (as prop) that forward native attributes while preserving type safety.

FAQ

Why avoid React.FC?

React.FC adds implicit children and can obscure prop inference; prefer explicit prop interfaces for clarity.

When should I use ComponentProps<'button'>?

Use it when you want your component to accept the same attributes as a native element, ensuring compatibility and accurate autocomplete.