【问题标题】:How to import a React proptypes typed component as type any into a React Typescript component如何将 React proptypes 类型化组件作为任何类型导入 React Typescript 组件
【发布时间】:2021-07-11 08:46:47
【问题描述】:

我们在 proptypes 中完成了相当大的组件库,并且我们正在转向 typescript。

因此,当我将 .jsx 组件移动为 .tsx 组件时,导入的 .jsx 组件突然开始抛出打字错误,导入的组件目前没有任何问题,我不能只是重写它的打字稿到处都在使用,目前它会比付出更多的努力。

为了解决这个问题,我做了以下操作(删除了很​​多中间代码)

import MyReactComponent from 'path/to/component';

const FixedMyReactComponent: any = MyReactComponent;

return <FixedMyReactComponent/>

它可以工作,我的错误消失了,但我觉得这很烦人,我宁愿不必制作 FixedMyReactComponent 并在本地为其设置类型,并且(正如我已经说过的)我不想要现在花时间解决打字稿不理解我的组件的事实,所以我想找到一些方法来全局告诉打字稿忽略你从 js / jsx 得到的类型错误,只报告来自 .ts 的错误/.tsx.

我想应该是这样的

declare module '*.jsx' {
  var _: React.Component<any, any>;
  export default _;
}

但这似乎没有我想要的效果。

【问题讨论】:

  • 你可以试试JSX.Element
  • @antoineso 嘿,我澄清了问题,据我了解,您建议我使用 JSX.Element 而不是我认为不错的任何东西,但它本身并不是使用任何困扰我的东西,它必须通过声明一个看起来非常h​​acky的新变量在组件中本地完成。我想要某种全局解决方案,这样我就不必制作 FixMyReactComponent 而不必花时间让我的经典 react proptype 验证组件与 typescript 组件配合得很好,因为我现在没有时间。
  • @jimmy 不,我现在不想让 proptypes 文件成为打字稿文件。我想在打字稿文件中使用 proptypes 文件。这给了我一个错误,除非我做了 MyComp2 any = MyComp - 我发现这不优雅,并且希望能够在全局级别上说 - 当将 proptypes 组件导入打字稿组件时,打字稿编译器将 proptypes 组件视为类型任何 - 当然假设 proptypes 库将处理它自己的 proptypes 文件。如果这可能存在问题并产生广泛的副作用,请权威地评论原因。
  • 我不确定您遇到的错误是否与整个 TSX 和 JSX 有关。作为 POC,我可以将带有 proptypes 的 .JSX 组件导入到 .TSX 组件中,而无需添加诸如 :any 之类的类型。我可以将道具传递给它并且没有错误。也许需要发布更多代码。

标签: reactjs typescript


【解决方案1】:

将你的 proptypes 移动到一个类型,然后你就可以输入你的组件了。

import { FC } from 'react'

type FixedMyReactComponentProps = {
  id: string;
  name: string;
}

const FixedMyReactComponent: FC<FixedMyReactComponentProps> = ({name, id}) => {
...
}

但是,如果您必须输入任何内容。你声明返回类型:

const FixedMyReactComponent = (): any => {
  ...
}

【讨论】:

  • 是的,那么问题是我不想将要导入我的反应打字稿的组件重写为反应打字稿,我希望能够做一些事情,希望在某些配置中全局,这样当我将 proptypes 验证组件导入到 typescript 验证组件时,我不会突然收到验证错误,否则每次我决定重写一个文件时都必须重写多个文件。
  • 显然我想在 proptypes 级别维护验证错误或警告,并且我想要验证 typescript 输入,但我不希望 typescript 文件说你导入的这个 proptypes 文件没有通过我们的打字稿规则进行验证。我通过声明任何类型的新变量并将导入的组件分配给它来实现这一点。我只是不想总是这样做——我想在全球范围内这样做。
【解决方案2】:

如果你现在做这项工作的时间有限,你可以在所有新创建的 .ts?(x) 文件的顶部使用 // @ts-nocheck(在 TypeScript 中添加 v3.7 用于这个确切的用例)并逐渐将它们删除时间。这将类型检查 NOTHING 基本上将文件视为 javascript,同时导出文件中定义的任何显式或隐式类型。您可能还想松开 compilerOptions 之类的 this,直到您以后可以拧紧它们。


如果您确实有时间完成转换,您可以考虑使用 lyft 的 react-javascript-to-typescript-transform npm 包。它已被弃用,但似乎可以完成工作,至少对于 prop-type 到类型的转换而言。

从 react 的一个简单的 js 原型示例开始。

import PropTypes from 'prop-types';

class Greeting extends React.Component {
  render() {
    return (
      <h1>Hello, {this.props.name}</h1>
    );
  }
}

Greeting.propTypes = {
  name: PropTypes.string
};

安装模块...

npm install -g react-js-to-ts

运行此命令将所有js文件转换为ts。

react-js-to-ts ./**/*.js

然后该包将所有带有prop-types的js文件替换为带有prop接口的.tsx。

type GreetingProps = {
  name?: string
};
class Greeting extends React.Component<GreetingProps, {}> {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

适用于功能组件和类组件。我不确定这对于组件中可能包含的状态类型或其他非类型代码的行为如何,但这将是向前迈出的一大步。无论如何,该状态暂时可以很容易地输入为any。也不确定这个包对复杂原型(如PropTypes.shape 和PropTypes.arrayOf)的性能如何。

如果我是你,我会验证所有更改,但任何转换错误都应该通过类型错误非常明显。无需使用假的 js 到 ts 组件的转换。即使在运行此代码之后,如果您遇到太多类型错误,您也可以关闭 strict 模式,甚至在需要时添加 // @ts-nocheck,直到您的团队有足够的带宽来解决错误类型。

老实说,我认为这是最好的方法,任何其他试图欺骗 typescript 编译器的方法都将比这更困难和更hacky,或者提供与原始原型定义不一致的类型。

【讨论】:

  • 确定我用它来将基于 proptypes 的组件转换成一个打字稿,然后给我一个关于较低级别组件不起作用的错误,作为一个正常的工程规则,你是对的,最好是修复组件而不是尝试破解它,但有一些现实世界的限制,例如 - 非常大的代码库,所以增量改进最好,低级组件使用了很多地方 - 这两个限制意味着我不想修复低级组件现在。但是在经历了所有这些之后 - 我认为 ts-nocheck 对我来说是正确的答案。
  • 我授予赏金并将其标记为已接受的答案,恕我直言 tsc-nocheck 是解决问题的答案部分,因此最好在答案顶部突出显示,然后说一下你什么时候想把那个组件变成打字稿使用这个包 - 等等等等。
  • 是的,总有权衡取舍,我在顶部添加了一条关于使用 // @ts-nocheck 的说明,如果您时间有限的话。确实,用他们自己的话“使迁移更容易”为这个确切的用例添加了评论。很高兴有帮助。
猜你喜欢
  • 1970-01-01
  • 2016-09-25
  • 2019-07-25
  • 2019-11-18
  • 2019-11-09
  • 2016-11-15
  • 1970-01-01
  • 1970-01-01
  • 2018-04-14
相关资源
最近更新 更多