You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何合理组织React可复用组件Props类型定义?

React + TypeScript 通用类型与组件Props复用实践

首先明确核心原则:先区分「跨场景通用的业务实体类型」和「组件专属的Props类型」,二者职责不同,不要混为一谈,针对你的三个疑问,结合实际生产环境的开发经验给出具体方案:


1. 通用数据结构建议抽离到独立类型目录

如果Entry对应的字段结构需要在组件、列表、接口请求层多处复用,非常建议把纯业务数据结构抽离到独立的类型定义文件(可以放在src/types或者src/models目录下),命名为不带Props后缀的业务实体名,只描述业务数据本身的字段,不和任何组件、接口逻辑耦合:

// src/types/entry.ts
export interface Entry {
  id: string;
  label: string;
  dateAdded: Date;
  isComplete: boolean;
}

至于Entry组件要不要改成接收单个entry属性,纯粹是组件API设计的偏好,没有强制规范:

  • 如果习惯展开传参,就让组件Props继承通用的Entry类型,组件独有的属性(比如事件回调、样式类名)直接在Props里补充即可,不用重复定义通用字段:
// src/components/Entry.tsx
import type { Entry } from '@/types/entry';

interface EntryProps extends Entry {
  onToggle: (id: string) => void;
  onDelete: (id: string) => void;
  className?: string;
}

const Entry = ({ id, label, dateAdded, isComplete, onToggle, onDelete, className }: EntryProps) => {
  // 组件渲染逻辑
}
  • 如果习惯传单个对象属性,直接在Props里定义entry字段为Entry类型即可:
interface EntryProps {
  entry: Entry;
  onToggle: (id: string) => void;
  onDelete: (id: string) => void;
  className?: string;
}

const Entry = ({ entry, onToggle, onDelete, className }: EntryProps) => {
  const { id, label, dateAdded, isComplete } = entry;
  // 组件渲染逻辑
}

抽离通用类型后,列表组件、接口层都可以直接引入这个类型,不用依赖组件文件:

// 接口请求层
const fetchEntryList = async (): Promise<Entry[]> => {
  const res = await fetch('/api/entries');
  return res.json();
}

// 列表组件
interface EntriesListProps {
  entries: Entry[];
}
const EntriesList = ({ entries }: EntriesListProps) => {
  return entries.map(item => <Entry key={item.id} {...item} onToggle={/* 回调逻辑 */} onDelete={/* 回调逻辑 */} />)
}

2. Props类型定义在组件文件外不属于不良实践

判断类型应该放哪里的唯一标准是复用范围:

  • 如果Props类型只在当前组件内部使用,直接写在组件同文件里即可,甚至不用导出,没必要为了“符合规范”强行抽离,徒增维护成本。
  • 如果有其他模块需要复用这个Props类型(比如写组件测试、封装组件高阶包装器),直接从组件文件导出Props类型完全是合理做法,不存在任何问题。

3. 所谓EntryProps命名语义误导本质是类型职责混淆

你觉得命名有误导,核心是把「通用业务数据类型」和「组件专属Props类型」的职责搞混了:

  • 跨场景复用的纯业务数据类型,统一以实体名命名(比如Entry),放在独立的types/models目录下,所有需要用到业务数据结构的地方都从这里引入,不会有任何歧义。
  • 组件专属的Props类型,本身就是描述组件入参的结构,命名为XxxProps天经地义,哪怕导出,其他开发者看到名字就知道这是Entry组件的入参类型,语义完全准确,不存在误导。

几个落地的小提示

  • 导入类型时优先用import type语法,可以避免类型定义被打包进运行时代码,减小产物体积。
  • 不要把组件独有的属性(比如事件回调、样式配置)加到通用业务类型里,保持业务类型的纯净,避免污染接口层、其他业务模块的类型定义。
  • 不要过度抽离类型,只有单文件使用的类型直接就近定义在使用的文件里,维护效率最高。

内容的提问来源于stack exchange,提问作者Max

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:36:26