首页 > 解决方案 > 为用 TypeScript 编写的 React 组件生成 PropTypes

问题描述

我们正在为我们的内部应用程序创建一个组件库。该库的旧版本是用 and 编写的JavaScriptJSX因此我们propTypes为所有组件声明了类型安全。
较新版本的组件库是用TypeScript. 为了类型安全,我们使用PropTypes了以下接口 -

interface Props {
    size?: 'small' | 'large';
    color?: string;
    text?: string;
}
export class MyComponent extends React.Component<Props, any> { ... }

这工作得很好,因为使用这些组件的新项目也是用 TypeScript 编写的(我们确实d.ts为所有组件类发布文件)。现在我们也需要更新旧项目中的组件库。由于他们没有使用 TypeScript,因此类型安全不起作用。他们仍然依赖旧的 propTypes 方式来保证类型安全。

//Usage of MyComponent
<MyComponent size={20} color={'red'} text={'HelloWorld'} />
//Size must be one of 'small' or 'large' not the numeric value.

所以我的问题是,如何处理在非 TypeScript 项目中使用 TypeScript(和 tsx)编写的组件的问题?

我已经确定了一些方法-

还有其他更清洁、更少手动的方法吗?

标签: javascriptreactjstypescript

解决方案


一个完美的问题!我现在正在自己研究这个确切的问题。

首先,我同意 TypeScript 不是 PropTypes 的 100% 替代品,因为:

  1. 如果您正在构建一个库并且它正在被原生 JavaScript 中的项目所使用,那么类型化无法帮助检测所有问题。

  2. PropTypes 在运行时动态工作,而 TypeScript 检查仅静态运行。

  3. PropTypes 可用于在运行时获取有关组件的信息,而类型定义在运行时会丢失。

我的搜索向我展示了以下可能性:

它允许在 TypeScript 编译期间实际生成 PropType。它作为 Babel 的插件工作。缺点是您必须使用 Babel 才能使用此功能。其实我已经发了一个问题:在没有 Babel 的情况下使用插件?,但我怀疑这是否可能。

正如我从文档中看到的,这不是一个完全兼容的 PropTypes 生成器,而是一个替代品,它使用它自己的实现在运行时进行类型检查。不过,我希望我的 PropTypes 与官方实现完全兼容。


您必须选择什么是您可以接受的以及您的项目的要求是什么。如果你对使用 Babel 没问题,我会推荐第一选择。但是,如果您只需要确保类型检查在运行时有效,那么第二种方法可能是可行的。

至于我,我想我现在必须让 TypeScript 类型和手动 PropTypes 保持同步,因为我没有使用 Babel,而且我不太喜欢自定义 PropTypes 实现。

或许,在某个阳光明媚的日子里,我们会找到一些资源,在我们公司实际编写我们自己的 PropTypes 生成器,并与大家分享。


这是一个打字技巧,可用于使 PropTypes 与打字保持同步:

import * as PropTypes from 'prop-types';
import React, {PureComponent} from 'react';


export interface IconProps {
  name: string;
}

export class Icon extends PureComponent<IconProps> {

  static propTypes: { [key in keyof IconProps]: any } = {
    name: PropTypes.string
  };

  render() {
    return <i className="dc-icon">{this.props.name}</i>;
  }

}

这将强制propTypes对象具有与您的道具接口完全相同的属性。


推荐阅读