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

TypeScript中如何提取接口或typeof类型中的泛型?

解决React泛型组件接口中提取泛型类型的问题

你遇到的核心问题是:MyAtomComponent['WithSomeOption']提取出来的是泛型函数类型,而非泛型类型别名——TypeScript中,泛型函数是“调用时才指定泛型参数的函数”,你没法直接把它当作泛型类型来传参使用。要解决这个问题,需要重构接口定义,把泛型参数从函数级别提升到类型级别,或者通过工具类型间接提取。

方案一:提前抽离泛型Props类型

最直接的方式是把组件的Props类型单独定义为泛型类型,再在接口中引用,后续复用更清晰:

import React from 'react';

// 1. 抽离泛型Props类型
type AtomBaseProps<P> = P;
type AtomWithOptionProps<P> = P;

// 2. 重构组件接口
interface MyAtomComponent {
  <P>(props: AtomBaseProps<P>): React.ReactElement;
  WithSomeOption: <P>(props: AtomWithOptionProps<P>) => React.ReactElement;
}

// 3. 组件实现
const MyAtomComponent: MyAtomComponent = <P>(props: P) => {
  return <div>{JSON.stringify(props)}</div>;
};

MyAtomComponent.WithSomeOption = <P>(props: P) => {
  return <div className="option">{JSON.stringify(props)}</div>;
};

// 4. 提取并复用泛型类型
type MoleculeProps<P> = { 
  // Molecule自身的Props
  moleculeLabel: string 
} & AtomWithOptionProps<P>;

// 现在Molecule可以正常接收泛型参数
const Molecule = <P>({ moleculeLabel, ...atomProps }: MoleculeProps<P>) => {
  return (
    <div>
      <span>{moleculeLabel}</span>
      <MyAtomComponent.WithSomeOption {...atomProps} />
    </div>
  );
};

// 使用示例
<Molecule<{ value: number }> moleculeLabel="测试" value={123} />

方案二:通过工具类型提取泛型函数的Props

如果不想修改原有接口结构,可以用TypeScript内置的Parameters工具类型,从泛型函数中提取其Props类型:

import React from 'react';

// 原有接口定义不变
interface MyAtomComponent {
  <P>(props: P): React.ReactElement;
  WithSomeOption: <P>(props: P) => React.ReactElement;
}

// 组件实现不变
const MyAtomComponent: MyAtomComponent = <P>(props: P) => {
  return <div>{JSON.stringify(props)}</div>;
};

MyAtomComponent.WithSomeOption = <P>(props: P) => {
  return <div className="option">{JSON.stringify(props)}</div>;
};

// 提取WithSomeOption的Props类型(借助Parameters)
type GetAtomWithOptionProps<P> = Parameters<MyAtomComponent['WithSomeOption']>[0];

// 定义Molecule的Props类型
type MoleculeProps<P> = {
  moleculeLabel: string
} & GetAtomWithOptionProps<P>;

// 实现Molecule组件
const Molecule = <P>({ moleculeLabel, ...atomProps }: MoleculeProps<P>) => {
  return (
    <div>
      <span>{moleculeLabel}</span>
      <MyAtomComponent.WithSomeOption {...atomProps} />
    </div>
  );
};

// 使用示例
<Molecule<{ text: string }> moleculeLabel="文本" text="Hello World" />

为什么之前的方法失败?

  • 你尝试的type AtomPropsWithGeneric = MyAtomComponent['WithSomeOption']得到的是(props: P) => React.ReactElement这种泛型函数类型,它只能在调用函数时指定P,不能直接当作AtomPropsWithGeneric<{}>来用。
  • type AtomPropsWithGeneric<P> = MyAtomComponent['WithSomeOption']<P>语法错误,因为TypeScript不支持直接对提取的函数类型进行泛型实例化,必须通过工具类型或者提前抽离的方式处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 01:20:36