如何避免使用 Typescript 在 React 构造函数中重新声明 props 类型 [英] How to avoid redeclaring props type in React constructor using Typescript
问题描述
假设我有一堂这样的课:
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
本身不应该变得非常丑陋",因为类型可以单独定义为 type
或 interface
以防参数类型冗长.
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
参数被传递给 super
,this.props
和 props
在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屋!