反应 15,打字稿 2.2.1。如何为 functional/stateless 个组件转换类型?

React 15, Typescript 2.2.1. How to cast types for functional/stateless components?

我正在阅读 this tutorial 以获取有关如何在我的组件中使用类型的一些线索。但到目前为止,我的感觉是它是做作和冗长的。从一个漂亮简洁的代码,我们得到了一些非常难以阅读的东西。最优雅的方法是什么?似乎关于这个主题的信息很少而且经常过时。使用 TS 和 React 的人并不多。

React.StatelessComponent<React.HTMLProps<JSX.Element>>React.StatelessComponent<{}> 好吗?

一切都是从这个错误开始的[ts] Property 'propTypes' does not exist on type '({match, onClick, completed, text}: EntityPage) => Element'.

我当前的设置:

import * as React from "react";
import { PropTypes } from "react";
import * as classNames from 'classnames';

interface EntityPage {
    match: any,
    onClick(): void,
    completed: boolean,
    text: string
}

export const EntityPageCmp: React.StatelessComponent<{}> = 
    ({ match, onClick, completed, text }: EntityPage) => {

    // Styles
    require('./entity-page.cmp.scss');
    let classes = classNames('entity-page-cmp'),
        titleClasses = classNames('title', { active: completed });

    return (
        <div className={classes} >
            <h3 className={titleClasses}>
                Entity: {match.params.entityId}
            </h3>
            {text}
        </div>
    )
}

EntityPageCmp.propTypes = {
    onClick: PropTypes.func.isRequired,
    completed: PropTypes.bool.isRequired,
    text: PropTypes.string.isRequired
}

export default EntityPageCmp

StatelessComponent 接口将你的 prop 定义作为类型参数,所以你应该这样写

export const EntityPageCmp: React.StatelessComponent<EntitPage> = 
    ({ match, onClick, completed, text }) => {
  ...
}

我看到你声明了两次道具。一次是 typescript 方式,第二次是 react 方式。

Typescript 在编译期间为您提供类型安全,并且这一行就足够了:React.StatelessComponent<EntitPage>

与 Typescript props 相反,React props 在运行时给你验证,当 react 检测到错误的 属性 类型时,控制台上会出现错误。如果你想拥有它,你需要编写 React 道具。

对于大多数情况,Typescript 验证就足够了,因此您不需要重复您的 props,您可以删除这些行

EntityPageCmp.propTypes = {
    onClick: PropTypes.func.isRequired,
    completed: PropTypes.bool.isRequired,
    text: PropTypes.string.isRequired
}

如果你真的想同时拥有两者,你可以使用一些库,比如 https://github.com/gcanti/prop-types-ts to get that without boilerplate. Unfortunately typescript doesn't support it natively. Here is an open issue for that https://github.com/Microsoft/TypeScript/issues/4833