javascript - 为用 TypeScript 编写的 React 组件生成 PropTypes
问题描述
我们正在为我们的内部应用程序创建一个组件库。该库的旧版本是用 and 编写的JavaScript
,JSX
因此我们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)编写的组件的问题?
我已经确定了一些方法-
- 对 d.ts 文件使用一些解析器
- 为所有组件创建一个 HoC
- 手动为所有组件编写 propTypes 和接口。
还有其他更清洁、更少手动的方法吗?
解决方案
一个完美的问题!我现在正在自己研究这个确切的问题。
首先,我同意 TypeScript 不是 PropTypes 的 100% 替代品,因为:
如果您正在构建一个库并且它正在被原生 JavaScript 中的项目所使用,那么类型化无法帮助检测所有问题。
PropTypes 在运行时动态工作,而 TypeScript 检查仅静态运行。
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
对象具有与您的道具接口完全相同的属性。
推荐阅读
- pandas - 基于行号/索引的 Pandas Dataframe 掩码
- dialogflow-es - Dialogflow 是否可以链接到像谷歌这样的搜索引擎?
- php - 一旦用户在表单上输入数据,php函数就不会运行
- javascript - 使用 if 和括号符号理解 reduce 函数
- python - 2个列表/数组中每次迭代的函数
- angular - Web应用程序从后端重定向到前端的支付网关集成问题
- php - Whoops\Exception\ErrorException 声明 Gantry 必须兼容 Twig\TokenParser\TokenParserInterface
- c# - 覆盖重载 C#
- html - 剃刀语法值未在 TextBoxFor 中设置
- python - 如何解决此错误:AttributeError:'NoneType' 对象没有属性'_inbound_nodes'?