React 组件中的 TypeScript 泛型

发布: (2026年1月8日 GMT+8 23:25)
3 min read
原文: Dev.to

Source: Dev.to

介绍

泛型并不是在 React 组件中每天都会用到的东西,但在某些情况下,它们可以让你编写既灵活又类型安全的组件。

基础组件定义

不带 Props

// Just FC component with no props
const Component = () => Hey ya!!!;

使用 React.FC 的 Props

// FC component with props
interface Props {
  name: string;
}

const Component: React.FC = ({ name }) => (
  Hey {name} ya!!!
);

React.FC 因为一些原因已经不太受欢迎,其中之一是它无法以我们有时需要的方式处理泛型。不过,很多开发者仍然因为可读性而继续使用它。

不使用 React.FC

// FC component with simple props
interface Props {
  name: string;
}

const Component = ({ name }: Props) => Hey {name} ya!!!;

何时需要泛型

考虑一种情况:组件从 API 接收一个包含数组的 DTO(数据传输对象)。组件需要显示一个代表“名称”的属性,但不同 DTO 中的属性名可能不同。

示例 DTO

interface ResponseDTO {
  id: number;
  name: string;
}

与特定 DTO 绑定的组件

interface ExampleProps {
  data: ResponseDTO[];
  getName: (item: ResponseDTO) => string;
}

export const Example = ({
  data,
  getName = (item) => item.name,
}: ExampleProps) => (
  
    {data.map((item) => (
      {getName(item)}
    ))}
  
);

因为组件知道 ResponseDTO 的确切结构,这段代码可以工作。如果我们希望组件能够处理 任何 具有“类似名称”值的 DTO,就需要使用泛型。

泛型 Props 接口

interface Props {
  data: T[];
  getName: (item: T) => string;
}

泛型参数 Tdata 数组和 getName 回调绑定在一起,确保它们操作的是同一种类型。

泛型组件

export const NameViewer = ({ data, getName }: Props) => (
  <>
    Look at the names:
    {data.map((item) => (
      {getName(item)}
    ))}
  
);

注意:.tsx 文件中,写成 “(尾随逗号)可以将泛型声明与 JSX 语法区分开来。

使用泛型组件

const unknownTypeData = [
  { id: 1, nameProp: 'John' },
  { id: 2, nameProp: 'Jane' },
];

const anotherUnknownTypeData = ['Foo', 'Bar'];

export const BusinessComponent = () => (
  
     item.nameProp}
    />
     item}
    />
  
);

只要提供合适的 getName 函数,NameViewer 现在就可以接受任何类型的数据。

结论

这个简单的例子展示了泛型如何让 React 组件能够适配各种数据结构,同时保持类型安全。在后续文章中,我们将探讨更高级的模式,例如条件泛型。

Back to Blog

相关文章

阅读更多 »

InkRows 背后的技术栈

InkRows InkRowshttps://www.inkrows.com/ 是一款现代的 note‑taking app,旨在在 web 和 mobile platforms 之间无缝工作。背后其简洁、直观的...

React 编码挑战:卡片翻转游戏

React 卡片翻转游戏 – 代码 tsx import './styles.css'; import React, { useState, useEffect } from 'react'; const values = 1, 2, 3, 4, 5; type Card = { id: numb...