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
相关产品推荐
相关产品推荐

