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



我正在尝试使用泛型和接口来制作React组件。

interface MyAtomComponent {
<P>(props: P): React.ReactElement;
WithSomeOption: <P>(props: P): React.ReactElement;
}
// component definition
const MyAtomComponent: MyAtomComponent = <P,>(props: P) => { ... };
MyAtomComponent.WithSomeOption = <P,>(props: P) => { ... };
// in use
<MyAtomComponent<{/* something */}> />
<MyAtomComponent.WithSomeOption<{/* something */}> />

看起来不错,但是在这种情况下出现了问题:

type MoleculeProps = {/* molecule prop */} & MyAtomComponent['WithSomeOption'] // Generic of WithSomeOption is gone
const Molecule = ({...}: MoleculeProps<number>) => { ... }; // I cannot put `number` because MoleculeProps is not generic

我试过了:

type AtomPropsWithGeneric = MyAtomComponent['WithSomeOption'];
// AtomPropsWithGeneric is now <P>(props: P): React.ReactElement
const Test: AtomPropsWithGeneric<{}> = ... // AtomPropsWithGeneric is not generic.

,这个也失败了:

type AtomPropsWithGeneric<P> = MyAtomComponent['WithSomeOption']<P>; // ';' expected

我认为[]在类型中不能提取泛型;typeof也打印同样的错误(';' expected)。

有什么方法可以在接口中提取泛型类型?


stack overflow暗示了这个答案,但我认为这种情况有点不同。

你可以使用实例化表达式:

type WithSomeOption<P> = typeof MyAtomComponent.WithSomeOption<P>;

使用点访问而不是括号表示法是非常重要的,因为后者将无法解析:

// not valid TS
type WithSomeOption<P> = typeof MyAtomComponent["WithSomeOption"]<P>;

我们还需要typeof,因为接口上的点访问是不允许的(否则它可能被误认为是名称空间):

// will error; "Cannot access 'MyAtomComponent.WithSomeOption' because 'MyAtomComponent' is a type, but not a namespace."
type WithSomeOption<P> = MyAtomComponent.WithSomeOption<P>;

游乐场

最新更新