首页 > 解决方案 > 在复合组件上声明附加成员

问题描述

问题:如何在 React 功能组件上声明最终存在的附加函数和属性(简称:成员),在编译时无法推断,因为它们将在运行时通过函数调用添加到组件中。

上下文:我编写了一个小型库,可以通过其他成员来扩充任何 React 功能组件。扩充发生在单独的函数调用中,因此类型推断不会拾取添加的成员。将添加的成员声明为事实并不满足打字稿编译器。

以下(简化)片段说明了我的难题:

import React from 'react';
import {augmentWithBob, addFooFunction, addBarProperty} from 'awesome-atomic-augmenter';

const Greeter = ({ greeting, className }) => (
  <div className={'greeter ' + className}>{greeting}!</div>
);
augmentWithBob(Greeter);
addFooFunction(Greeter);
addBarProperty(Greeter);

export { Greeter };

增强的组件可以这样使用:

<Greeter />
<Greeter.Bob />
Greeter.foo(Greeter.bar)

我尝试过的:为了保持简短,让我们只关注addFooFunction.

import React from 'react';
import type { FunctionComponent, HTMLAttributes } from 'react';
import { addFooFunction } from 'awesome-atomic-augmenter';

interface GreeterProps extends HTMLAttributes<Element> {
  greeting: string;
}
interface IGreeter extends FunctionComponent<GreeterProps> {
  foo(input: any): any;
}

const GreeterImpl = ({ greeting, className }: GreeterProps) => (/*...*/);
addFooFunction(GreeterImpl);

const Greeter: IGreeter = GreeterImpl;

export { Greeter };

但这无法编译。Typescript 编译器输出:

C:/tinkerspace/react-typescript-testground/src/Greeter.tsx 中的 TypeScript 错误:类型“({ greeting, className }: GreeterProps) => ReactElement”中缺少属性“foo”,但在“IGreeter”类型中是必需的。TS2741

我的主要资源是声明合并。提到了一个关于模块增强的神秘咒语,我没有尝试过,我只会将其视为最后的手段,因为它需要我将组件实现和增强拆分为两个不同的文件。这很丑陋。

标签: reactjstypescript

解决方案


推荐阅读