typescript-react-patterns by asyrafhussin/agent-skills
npx skills add https://github.com/asyrafhussin/agent-skills --skill typescript-react-patterns适用于 React 应用程序的全面 TypeScript 模式。包含 7 个类别下的 35 条以上规则,用于构建类型安全、可维护的 React 代码。
在以下情况下参考这些指南:
| 优先级 | 类别 | 影响 | 前缀 |
|---|---|---|---|
| 1 | 组件类型定义 | 关键 | comp- |
| 2 | 钩子类型定义 | 关键 | hook- |
| 3 | 事件处理 | 高 |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
event-| 4 | Ref 类型定义 | 高 | ref- |
| 5 | 通用组件 | 中 | generic- |
| 6 | 上下文与状态 | 中 | ctx- |
| 7 | 工具类型 | 低 | util- |
comp-props-interface - 对属性使用接口,对联合类型使用 typecomp-children-types - 正确的子元素类型模式comp-default-props - TypeScript 中的默认属性comp-forward-ref - 为 forwardRef 组件添加类型comp-compound - 复合组件模式comp-polymorphic - "as" 属性类型定义hook-usestate - 正确类型的 useStatehook-useref - 用于 DOM 和可变值的 useRefhook-useeffect - useEffect 清理函数类型定义hook-usereducer - 使用可辨识联合类型的 useReducerhook-custom-return - 自定义钩子返回类型hook-generic - 通用自定义钩子event-handler-types - 事件处理器类型模式event-synthetic - SyntheticEvent 类型event-form - 表单事件处理event-keyboard - 键盘事件类型event-mouse - 鼠标事件类型event-custom - 自定义事件类型ref-dom-elements - DOM 元素的 Refsref-mutable - 可变 Ref 模式ref-callback - 回调 Ref 类型定义ref-forward - 转发 Refsref-imperative-handle - useImperativeHandle 类型定义generic-list - 通用列表组件generic-form - 通用表单组件generic-select - 通用选择/下拉组件generic-table - 通用表格组件generic-constraints - 通用约束ctx-create - 创建类型化的上下文ctx-provider - Provider 类型定义模式ctx-consumer - 正确类型的 useContextctx-reducer - 带有 reducer 的上下文ctx-default-value - 处理默认值util-react-types - 内置的 React 类型util-component-props - ComponentProps 工具类型util-pick-omit - 用于属性的 Pick 和 Omitutil-discriminated-unions - 状态机util-assertion-functions - 类型断言函数// 对属性使用接口(可扩展)
interface ButtonProps {
variant: 'primary' | 'secondary' | 'danger'
size?: 'sm' | 'md' | 'lg'
isLoading?: boolean
children: React.ReactNode
onClick?: () => void
}
// 对联合类型使用 type
type ButtonVariant = 'primary' | 'secondary' | 'danger'
function Button({
variant,
size = 'md',
isLoading = false,
children,
onClick,
}: ButtonProps) {
return (
<button
className={`btn-${variant} btn-${size}`}
onClick={onClick}
disabled={isLoading}
>
{isLoading ? 'Loading...' : children}
</button>
)
}
// ReactNode - 最灵活(字符串、数字、元素、数组、null)
interface CardProps {
children: React.ReactNode
}
// ReactElement - 仅限 JSX 元素
interface WrapperProps {
children: React.ReactElement
}
// 渲染属性模式
interface DataFetcherProps<T> {
children: (data: T) => React.ReactNode
}
// 特定元素类型
interface TabsProps {
children: React.ReactElement<TabProps> | React.ReactElement<TabProps>[]
}
// 表单事件
function Form() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
// 处理提交
}
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value)
}
const handleSelect = (e: React.ChangeEvent<HTMLSelectElement>) => {
console.log(e.target.value)
}
return (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} />
<select onChange={handleSelect}>
<option>A</option>
<option>B</option>
</select>
</form>
)
}
// DOM 元素 ref
function Input() {
const inputRef = useRef<HTMLInputElement>(null)
const focus = () => {
inputRef.current?.focus()
}
return <input ref={inputRef} />
}
// 可变 ref(非 null,存储值)
function Timer() {
const intervalRef = useRef<number | undefined>(undefined)
useEffect(() => {
intervalRef.current = window.setInterval(() => {
// 计时
}, 1000)
return () => {
clearInterval(intervalRef.current)
}
}, [])
}
// 通用列表组件
interface ListProps<T> {
items: T[]
renderItem: (item: T, index: number) => React.ReactNode
keyExtractor: (item: T) => string | number
}
function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
return (
<ul>
{items.map((item, index) => (
<li key={keyExtractor(item)}>{renderItem(item, index)}</li>
))}
</ul>
)
}
// 用法 - T 被推断
<List
items={users}
renderItem={(user) => <UserCard user={user} />}
keyExtractor={(user) => user.id}
/>
interface AuthContextType {
user: User | null
login: (credentials: Credentials) => Promise<void>
logout: () => void
isLoading: boolean
}
const AuthContext = createContext<AuthContextType | null>(null)
export function useAuth() {
const context = useContext(AuthContext)
if (!context) {
throw new Error('useAuth must be used within AuthProvider')
}
return context
}
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null)
const [isLoading, setIsLoading] = useState(true)
const login = async (credentials: Credentials) => {
// 实现
}
const logout = () => {
setUser(null)
}
return (
<AuthContext.Provider value={{ user, login, logout, isLoading }}>
{children}
</AuthContext.Provider>
)
}
阅读各个规则文件以获取详细解释和代码示例:
rules/comp-props-interface.md
rules/hook-usestate.md
rules/event-handler-types.md
每个规则文件包含:
每周安装量
83
代码仓库
GitHub 星标数
11
首次出现
Jan 21, 2026
安全审计
安装于
codex64
opencode64
gemini-cli60
claude-code58
github-copilot56
cursor54
Comprehensive TypeScript patterns for React applications. Contains 35+ rules across 7 categories for building type-safe, maintainable React code.
Reference these guidelines when:
| Priority | Category | Impact | Prefix |
|---|---|---|---|
| 1 | Component Typing | CRITICAL | comp- |
| 2 | Hook Typing | CRITICAL | hook- |
| 3 | Event Handling | HIGH | event- |
| 4 | Ref Typing | HIGH | ref- |
| 5 | Generic Components | MEDIUM | generic- |
| 6 | Context & State | MEDIUM | ctx- |
| 7 | Utility Types | LOW | util- |
comp-props-interface - Use interface for props, type for unionscomp-children-types - Correct children typing patternscomp-default-props - Default props with TypeScriptcomp-forward-ref - Typing forwardRef componentscomp-compound - Compound component patternscomp-polymorphic - "as" prop typinghook-usestate - useState with proper typeshook-useref - useRef for DOM and mutable valueshook-useeffect - useEffect cleanup typinghook-usereducer - useReducer with discriminated unionshook-custom-return - Custom hook return typeshook-generic - Generic custom hooksevent-handler-types - Event handler type patternsevent-synthetic - SyntheticEvent typesevent-form - Form event handlingevent-keyboard - Keyboard event typesevent-mouse - Mouse event typesevent-custom - Custom event typesref-dom-elements - Refs for DOM elementsref-mutable - Mutable ref patternref-callback - Callback ref typingref-forward - Forwarding refsref-imperative-handle - useImperativeHandle typinggeneric-list - Generic list componentsgeneric-form - Generic form componentsgeneric-select - Generic select/dropdowngeneric-table - Generic table componentsgeneric-constraints - Generic constraintsctx-create - Creating typed contextctx-provider - Provider typing patternsctx-consumer - useContext with proper typesctx-reducer - Context with reducerctx-default-value - Handling default valuesutil-react-types - Built-in React typesutil-component-props - ComponentProps utilityutil-pick-omit - Pick and Omit for propsutil-discriminated-unions - State machinesutil-assertion-functions - Type assertions// Use interface for props (extendable)
interface ButtonProps {
variant: 'primary' | 'secondary' | 'danger'
size?: 'sm' | 'md' | 'lg'
isLoading?: boolean
children: React.ReactNode
onClick?: () => void
}
// Use type for unions
type ButtonVariant = 'primary' | 'secondary' | 'danger'
function Button({
variant,
size = 'md',
isLoading = false,
children,
onClick,
}: ButtonProps) {
return (
<button
className={`btn-${variant} btn-${size}`}
onClick={onClick}
disabled={isLoading}
>
{isLoading ? 'Loading...' : children}
</button>
)
}
// ReactNode - most flexible (string, number, element, array, null)
interface CardProps {
children: React.ReactNode
}
// ReactElement - only JSX elements
interface WrapperProps {
children: React.ReactElement
}
// Render prop pattern
interface DataFetcherProps<T> {
children: (data: T) => React.ReactNode
}
// Specific element type
interface TabsProps {
children: React.ReactElement<TabProps> | React.ReactElement<TabProps>[]
}
// Form events
function Form() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
// handle submit
}
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value)
}
const handleSelect = (e: React.ChangeEvent<HTMLSelectElement>) => {
console.log(e.target.value)
}
return (
<form onSubmit={handleSubmit}>
<input onChange={handleChange} />
<select onChange={handleSelect}>
<option>A</option>
<option>B</option>
</select>
</form>
)
}
// DOM element ref
function Input() {
const inputRef = useRef<HTMLInputElement>(null)
const focus = () => {
inputRef.current?.focus()
}
return <input ref={inputRef} />
}
// Mutable ref (no null, stores values)
function Timer() {
const intervalRef = useRef<number | undefined>(undefined)
useEffect(() => {
intervalRef.current = window.setInterval(() => {
// tick
}, 1000)
return () => {
clearInterval(intervalRef.current)
}
}, [])
}
// Generic list component
interface ListProps<T> {
items: T[]
renderItem: (item: T, index: number) => React.ReactNode
keyExtractor: (item: T) => string | number
}
function List<T>({ items, renderItem, keyExtractor }: ListProps<T>) {
return (
<ul>
{items.map((item, index) => (
<li key={keyExtractor(item)}>{renderItem(item, index)}</li>
))}
</ul>
)
}
// Usage - T is inferred
<List
items={users}
renderItem={(user) => <UserCard user={user} />}
keyExtractor={(user) => user.id}
/>
interface AuthContextType {
user: User | null
login: (credentials: Credentials) => Promise<void>
logout: () => void
isLoading: boolean
}
const AuthContext = createContext<AuthContextType | null>(null)
export function useAuth() {
const context = useContext(AuthContext)
if (!context) {
throw new Error('useAuth must be used within AuthProvider')
}
return context
}
export function AuthProvider({ children }: { children: React.ReactNode }) {
const [user, setUser] = useState<User | null>(null)
const [isLoading, setIsLoading] = useState(true)
const login = async (credentials: Credentials) => {
// implementation
}
const logout = () => {
setUser(null)
}
return (
<AuthContext.Provider value={{ user, login, logout, isLoading }}>
{children}
</AuthContext.Provider>
)
}
Read individual rule files for detailed explanations and code examples:
rules/comp-props-interface.md
rules/hook-usestate.md
rules/event-handler-types.md
Each rule file contains:
Weekly Installs
83
Repository
GitHub Stars
11
First Seen
Jan 21, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
codex64
opencode64
gemini-cli60
claude-code58
github-copilot56
cursor54
Tailwind CSS v4 + shadcn/ui 生产级技术栈配置指南与最佳实践
2,600 周安装