React 开发应该了解的 TypeScript 模式

随着 TypeScript 在 React 生态系统中的采用率不断提高,了解高级模式可以显著提高您的代码质量、可扩展性和开发人员体验。本文重点介绍了 React 开发的基本 TypeScript 模式,以及帮助你充分利用这些工具的实际示例。

Discriminated unions (管理复杂的状态(数据))

Discriminated unions 是处理具有多个变体或 "模式" 的状态的有效方法。通过将联合类型与 "discriminator" 属性组合在一起,您可以确保类型安全并避免由无效状态引起的错误。

示例 状态加载

ts 复制代码
type FetchState =  
| { status: 'idle' }  
| { status: 'loading' }  
| { status: 'success'; data: string[] }  
| { status: 'error'; error: string };


const fetchReducer = (state: FetchState, action: any): FetchState => {  
  switch (action.type) {  
  case 'FETCH_START':  
    return { status: 'loading' };  
  case 'FETCH_SUCCESS':  
    return { status: 'success', data: action.payload };  
  case 'FETCH_ERROR':  
    return { status: 'error', error: action.payload };  
  default:  
    return state;  
  }  
};

为什么有用 Discriminated unions 允许您的状态转换是显式的,从而避免无效的组合,例如同时具有 dataerror

泛型:定义具有复用性和适应性的组件

泛型使你的组件或 hook 可重用,同时保留强类型定义。这对于处理具有不同数据结构的列表、表单或 API 特别有用。

示例, 可复用的表格组件

ts 复制代码
type TableProps<T> = {  
  data: T[];  
  renderRow: (item: T) => React.ReactNode;  
};  
  
function Table<T>({ data, renderRow }: TableProps<T>) {  
  return (  
    <table>  
      <tbody>
       {data.map((item, index) => <tr key={index}>{renderRow(item)}</tr>)}
      </tbody>  
  </table>);  
}

// Usage  
type User = { id: number; name: string };  
const users: User[] = [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];  
  
<Table  
  data={users}  
  renderRow={(user) => (<>  
    <td>{user.id}</td>  
    <td>{user.name}</td>  
  </>)}  
/>;

为什么有用

泛型使您的组件具有适应性,而不会失去类型推理的优势,从而使您免于重复的代码。

Mapped Types: props 和 state 之间的转换

映射类型允许您通过转换现有类型来创建新类型。这在定义派生 state 或 prop 接口时特别有用。

示例, 部分表单prpos

ts 复制代码
type FormValues = {  
  name: string;  
  email: string;  
  age: number;  
};

type FormErrors<T> = {  
  [K in keyof T]?: string;  
};

const errors: FormErrors<FormValues> = {  
  name: "Name is required",  
  email: "Email is invalid",  
};

为什么有用

映射类型非常适合管理具有不同属性的表单、API 或配置对象。

React props 和 state 的高级类型

带有 defaultProps 的类型属性

使用 defaultProps 时,您可以通过利用 TypeScript 的部分类型支持来确保类型安全

ini 复制代码
type ButtonProps = {  
  label: string;  
  onClick?: () => void;  
};  
  
const Button = ({ label, onClick = () => {} }: ButtonProps) => (  
  <button onClick={onClick}>{label}</button>  
);

只读 State

要在您的状态中强制执行不可变性,请使用 ReadonlyReadonlyArray

ts 复制代码
type State = Readonly<{  
  items: string[];  
}>;  
  
const [state, setState] = useState<State>({ items: ['Item 1'] });

为什么有用

强类型的 props 和 state 减少了运行时错误,并使其他开发人员清楚地了解了你的意图。

使用 TypeScript 和 React 的动态表单

动态表单通常涉及依赖于用户输入的复杂类型。TypeScript 可以帮助强制执行正确性,即使对于动态结构也是如此。

动态表单字段

ts 复制代码
type Field = {  
  id: string;  
  label: string;  
  value: string;  
};

type FormState = {  
  fields: Field[];  
};

const DynamicForm: React.FC = () => {  
const [formState, setFormState] = useState<FormState>({ fields: [] });  
  
const addField = () => {  
  setFormState((prev) => ({  
    fields: [...prev.fields, { id: Date.now().toString(), label: '', value: '' }],  
  }));  
};  
  
  return (  
    <div>  
      {formState.fields.map((field) => (  
        <input  
            key={field.id}  
            placeholder={field.label}  
            value={field.value}  
            onChange={(e) =>  
            setFormState((prev) => ({  
            fields: prev.fields.map((f) =>  
              f.id === field.id ? { ...f, value: e.target.value } : f  
            ),  
       }))}  
    />  
  ))}  
     <button onClick={addField}>Add Field</button>  
    </div>  
  );  
};

为什么有用

动态表单是许多应用程序中的常见功能。TypeScript 确保每个字段都正确键入和更新。

总结

TypeScript 不仅仅是一个静态类型工具------它还是一种编写更健壮、可维护和可扩展的 React 应用程序的方法。通过掌握 discriminated unions(可区分联合)、泛型和高级 prop 类型等模式,您可以在项目中释放 TypeScript 的全部潜力。无论您是构建动态表单、可重用组件还是管理复杂状态,这些模式都能确保流畅高效的开发体验。

原文地址(TypeScript Patterns You Should Know for React Development | by Dzmitry Ihnatovich | Medium)

广州有前端坑位滴滴我。

相关推荐
To_OC3 小时前
啃完 TS 工具类型我发现:Pick 和 Omit 原来就是一层窗户纸
前端·面试·typescript
风月说与山鬼4 小时前
三、大括号语法
前端·react.js
JaydenAI6 小时前
[TypeScript学习笔记-07]根据现有类型创建新类型的N种方式
typescript
东风破_11 小时前
TypeScript 高级类型进阶:keyof、Exclude、Record 与类型组合思想
前端·后端·typescript
晓说前端13 小时前
TypeScript 核心语法应用 —— Vue 3 中的使用(下)
前端·javascript·typescript·类型系统
东风破_14 小时前
(拼多多考题)TypeScript 工具类型:Pick、Omit、Partial、Required
typescript
rimydu1974art16 小时前
opencheck解读:拆解 OpenCheck 的歧视性条款识别与澄清问询机制
人工智能·typescript
Zkaisen18 小时前
mtreoCVE-2025-11953学习(目录遍历与远程命令执行)
学习·react native·react.js·metro
zzzzzz31019 小时前
react-bits 为什么会吸引前端开发者:别把动效当装饰,先把它当成页面能力
前端·react.js·动效
风月说与山鬼21 小时前
二、React入口文件(main.jsx)
前端·react.js