如何避免使用 Typescript 在 React 构造函数中重新声明 props 类型 [英] How to avoid redeclaring props type in React constructor using Typescript

查看:86
本文介绍了如何避免使用 Typescript 在 React 构造函数中重新声明 props 类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一堂这样的课:

Let's say I have a class like this:

class PeopleByTag extends React.Component<RouteComponentProps<{ tag: string }>

我需要在我的构造函数中做一些事情,在这个例子中获取数据,但要做到这一点,我需要声明一个 props 参数,但如果我不指定类型,它将变成任何类型:

I need to do something in my constructor, in this example fetch data, but to do that I need to declare a props parameter, but if I don't specify the type it will become any:

constructor(props) {
    super(props); // props is any
    this.loadData();
}

另一方面,如果我重新声明类型,代码会变得非常难看:

On the other hand, if I redeclare the type the code gets very ugly:

constructor(props: Readonly<{
    children?: React.ReactNode;
}> & Readonly<RouteComponentProps<{
    tag: string;
}, StaticContext, any>>) {
    super(props);
    this.loadData();
}

有没有办法从类扩展中自动推断出 props 类型,同时还能编写构造函数?

Is there a way to automatically infer the props type from the class extension while also being able to write a constructor?

我也不想使用已弃用的生命周期钩子(即 ComponentWillMount).

I also don't want to use the deprecated lifecycle hooks (i.e. ComponentWillMount).

推荐答案

通常 constructor 本身不应该变得非常丑陋",因为类型可以单独定义为 typeinterface 以防参数类型冗长.

Usually constructor itself shouldn't get 'very ugly', just because types can be defined separately as type or interface in case parameter types are verbose.

Constructor props 参数无法推断,因为 React.Component> 泛型参数引用父类,React.Component,不是当前类.

Constructor props parameter cannot be inferred because React.Component<RouteComponentProps<{ tag: string }>> generic parameter refers to parent class, React.Component, not current class.

正如在 类型定义,这为父构造函数推断正确的类型,即super.

As it can be seen in type definitions, this infers proper type for parent constructor, i.e. super.

所以这个

constructor(props) {
    super(props);
}

有效.this.props 仍然正确输入.

is valid. this.props is still properly typed.

如果使用 noImplicitAny 编译器选项,则为:

In case noImplicitAny compiler option is used, it is:

constructor(props: any) {
    super(props);
}

在构造函数中使用 props 类型为 any 可能会导致类型错误:

The use of props typed as any in constructor may result in type mistakes:

constructor(props: any) {
    super(props);

    props.tag; // ok
    props.nonexistentProp; // ok
}

虽然 this.props 是类型安全的.

While this.props is type-safe.

一个类可以被定义为泛型以在构造函数中维护正确的 props 类型,但这可能被认为是过度的:

A class can be typed with as generic to maintain proper props type in constructor, but this can be considered overkill:

export class PeopleByTag<P extends { tag: string }> extends React.Component<P> {
  constructor(props: Readonly<P>) {
    super(props); // props is any

    props.tag; // ok
    props.nonexistentProp; // not ok
    props.children; // not ok, but we rarely ever need children in constructor
  }
}

通过为其提供不兼容的类型来防止在构造函数中使用 props 可能是有益的:

It may be beneficial to prevent the use of props in constructor by providing incompatible type for it:

constructor(props: never) {
    super(props);

    props.tag; // not ok
}

如果 props 参数被传递给 superthis.propsprops 在JavaScript.它们在 TypeScript 中不可互换.this.props 可以在构造函数中访问以获取正确类型的 props.

If props argument was passed to super, this.props and props are interchangeable in JavaScript. They aren't interchangeable in TypeScript. this.props may be accessed in constructor for properly typed props.

这篇关于如何避免使用 Typescript 在 React 构造函数中重新声明 props 类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆