为 TypeScript 定义非箭头 React 功能组件?

Eva*_*nss 12 typescript reactjs

您可以使用以下命令在 TypeScript 中定义 React 功能组件的类型:

export const Component: React.FC = () => {
  return // Stuff
};
Run Code Online (Sandbox Code Playgroud)

你如何对非箭头函数做同样的事情?

function Component() {
  return // Stuff
}
Run Code Online (Sandbox Code Playgroud)

实践上有区别吗?这个流行的备忘单没有涵盖它,所以我想知道是否有理由不使用该语法?

https://github.com/typescript-cheatsheets/react-typescript-cheatsheet

win*_*iz1 6

如何对非箭头函数执行同样的操作?

import * as React from 'react';

function NonFatArrow(): React.ReactElement {
    return (
      <>
        Non-fat-arrow function
      </>
    );
}

const FatArrow: React.FunctionComponent = _props => {
  return (
    <section>
      <NonFatArrow/>
    </section>
  );
};

Run Code Online (Sandbox Code Playgroud)

实践上有什么区别吗?

撇开 React 和 Typescript 不谈,在 ES6 中,粗箭头函数捕获了一些东西,包括this并将捕获的内容带入 self。因此,如果有数千个这样的函数,那么就会产生捕获开销。

回到 React 和 Typescript,thisReact.FunctionComponent 中没有使用,但是如果您选择的 Typescript 转译器转译为 ES6,那么将会出现带有捕获的粗箭头函数。

因此,这一切都取决于所选的转译器及其设置。使用 Typescript 编译器,如果您有"target": "es5"tsconfig.json,那么该FatArrow组件将被转换为 ES5 function。更改设置以"target": "es6"确保FatArrow转换为箭头函数。使用 Babel 作为转译器,你的里程可能会有所不同。


Ser*_*nyk 4

当您使用 声明组件时,对于某些特定情况有更好的类型支持const。要了解这些情况,您可以查看以下React.FC类型:

type FC<P = {}> = FunctionComponent<P>;
interface FunctionComponent<P = {}> {
    (props: PropsWithChildren<P>, context?: any): ReactElement | null;
    propTypes?: WeakValidationMap<P>;
    contextTypes?: ValidationMap<any>;
    defaultProps?: Partial<P>;
    displayName?: string;

}
Run Code Online (Sandbox Code Playgroud)

由于 React 组件(甚至是函数组件)不仅仅是一个简单的函数 - 为组件本身指定精确的类型可以为您提供更好的类型推断:


function FooAsFunc({ children }) { // children has 'any' type
  return 1234
}

const FooAsConst: React.FC = ({ children }) => {
  return 1234 // type error: typescript knows that 1234 is not valid react component return type
}

FooAsFunc.displayName = new Date()
FooAsConst.displayName = new Date() // type error: 'displayName' suppose to be of a type string
Run Code Online (Sandbox Code Playgroud)

最后,通过function声明也可以实现相同的类型安全,但只是需要更多代码。