【问题标题】:How to use typescript jsdoc annotations for React PropTypes如何为 React PropTypes 使用 typescript jsdoc 注释
【发布时间】:2017-10-01 19:24:34
【问题描述】:

当使用 typescript 定义 react 组件时,我们可以这样写:

class SomeComponent extends React.Component<PropInterface, StateInterface> {
  // ...
}

有没有办法使用jsdoc annotations 进行等效操作并检查道具类型。

【问题讨论】:

  • 你用过React的内置PropTypes吗?
  • @AluanHaddad Typescript 最近通过 jsdoc 注释添加了类型检查支持。请参阅问题中的链接。
  • @AndrewLi 这已被弃用。而且我更希望在编译时进行检查。
  • @AluanHaddad 我打算写 .js 文件,它没有泛型,而是有 jsdoc cmets。
  • 它是,从什么时候开始的?你试过@property吗?

标签: javascript typescript jsdoc


【解决方案1】:

我更喜欢以下形式(es2015 + @types/react):

/**
 * @typedef {object} Props
 * @prop {string} className
 * @prop {number} numberProp
 *
 * @extends {Component<Props>}
 */
export default class SomeComponent extends Component {
    render() {
        return (
            <div className={this.props.className}>
                {this.props.numberProp}
            </div>
        );
    }

}

【讨论】:

    【解决方案2】:

    如果有人正在寻找替代解决方案。 关于这个Typescript issue你也可以这样实现。

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    /**
     * @augments {Component<{onSubmit:function, text:string}>}
     * @param {object} event - Input event
     * @return {React.ReactElement} - React component
    */
    class Test extends Component {
      handleInput = (event) => {
        event.preventDefault();
        this.props.onSubmit(event.target.value);
      };
    
      render() {
        const { text } = this.props;
        return <div>Hello, property :O {text}</div>;
      }
    }
    
    Test.propTypes = {
      onSubmit: PropTypes.func.isRequired,
      text: PropTypes.string.isRequired,
    };
    
    export default Test;
    

    【讨论】:

    • 运行时 PropTypes 检查与静态 typescript 检查混合在一起。我会放弃PropTypes,因为同时使用两者没有意义。
    【解决方案3】:

    这行得通,虽然它可能不是那么好。

    // Foo.jsx
    import * as React from 'react';
    
    /**
     * @type {{ new(props: any): {
         props: { a: string, b: number },
         state: any,
         context: any,
         refs: any,
         render: any,
         setState: any,
         forceUpdate: any
       } }}
     */
    const Foo = class Foo extends React.Component {
      render() {
        return <div className={this.props.a}>{this.props.b}</div>;
      }
    };
    export default Foo;
    
    // import Foo and use it in .tsx or .jsx file
    import Foo from './Foo';
    
    <Foo/>; // error: Type '{}' is not assignable to type '{ a: string; b: number; }'
    <Foo a='a' b={0}/>; // OK
    

    【讨论】:

    • 感谢您的回答。这行得通。您能否建议如何将传递未指定的道具标记为错误?例如。在您的示例中,如果我调用类似:&lt;Foo a='a' b={0} c={20}/&gt;,我不会收到任何错误。
    • 嗯,这很奇怪。当我用"compilerOptions": { "target": "es5", "allowJs": true, "checkJs": true, "jsx": "react" } 调用&lt;Foo a='a' b={0} c={20}/&gt; 时,我收到错误Property 'c' does not exist on type 'IntrinsicAttributes ...。我正在使用 TypeScript 2.3.2。
    • 我正在尝试将所有文​​件作为 js 文件(包括导入它的文件)以及// @ts-check。 tsconfig:`{“compilerOptions”:{“noEmit”:true,“allowJs”:true,“jsx”:“React”,“checkJs”:true,“allowJs”:true},“include”:[“./ src/" ] } `
    • 实际上当两个文件都是 js 时,根本不会发生类型验证。
    • 我创建了a repo on github,其中类型检查在(可能)与您的情况相同的情况下按预期工作。
    【解决方案4】:

    如果你使用 PropTypes,

    这样的东西对我有用:

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    /**
     * Test component
     * @augments {Component<Props, State>}
     */
    class Test extends React.Component {
      // ...
    }
    
    Test.propTypes = {
      title: PropTypes.string.isRequired,
    }
    
    export default class Test1 extends React.Component {
      render() {
        return <Test  />
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-11-18
      • 2015-06-02
      • 2013-08-13
      • 2017-05-25
      • 2020-10-15
      • 2015-01-31
      • 2016-05-12
      • 1970-01-01
      相关资源
      最近更新 更多