我正在用Typescript和Material ui编写一个ReactJS类.tsx文件.在我的一个自定义组件中,我想创建一个对我在自定义组件中使用的一个组件的引用.

export class MyTextField extends React.Component<MyProps, MyState> {
  private refTextField: React.RefObject<TextField>;
  constructor(props: MyProps) {
    super(props);
    this.refTextField = React.createRef();
  }

  render(): JSX.Element {
    const { id, label, value: defaultValue } = this.props;
    const { value } = this.state;
    const element = (
      <TextField ref={this.refTextField} id={id} label={label} defaultValue={defaultValue} value={value} />
    );

    return element;
  }
}

在编译过程中,我的引用声明出现了一个错误:

"TextField"指的是一个值,但在这里用作类型.TS2749

我试图在我的声明中加入"typeof TextField",但在我的render中判断ref属性时,我有另一条消息:

Type 'RefObject<(props: TextFieldProps) => Element>' is not assignable to type '((instance: HTMLDivElement | null) => void) | RefObject | null | undefined'. Type 'RefObject<(props: TextFieldProps) => Element>' is not assignable to type 'RefObject'. Type '(props: TextFieldProps) => Element' is missing the following properties from type 'HTMLDivElement': align, addEventListener, removeEventListener, accessKey, and 238 more. TS2322

有什么 idea 吗?

推荐答案

所以我以前在我的代码中多次遇到这个问题,但直到今天才弄明白发生这种情况的原因.

TL;DR在最后给出了问题的实际答案.

在TypeScript中创建类时,该类的名称同时引用实例类型和Javascript类值.如果将该类作为类型引用,TypeScript会自动将其检测为该类的实例类型.如果你在运行时引用这个类,它只会像Javascript中那样使用它.到目前为止一切都很好.

class MyClass {}
let abc: MyClass; // ts recognizes as instance type
abc = new MyClass(); // completely fine, used here as the javascript value

然而,真正的问题是从模块dynamically导出类时.以某种方式导出类时,TypeScript只能导出类的Javascript值,而不能导出类型.因此,如果您将其导入另一个模块并try 将其作为类型引用,您将得到TS2749.

let intervariable = class MyClass{}
export const MyClass = intervariable; // TypeScript does not export type here.
import {MyClass} from './myclass';

let abc: MyClass; // TypeScript error TS2749

当这种情况发生时,尤其是在您无法控制的情况下,我获取实例类型的解决方案只是使用InstanceType和typeof:

import {MyClass} from './myclass';

let abc: InstanceType<typeof MyClass>; // no error
// the rest...

typeof运算符获取类值的类构造函数类型,InstanceType generic获取所需的实例类型.

TL;博士:

Typescript相关问答推荐

在TypScript手册中可以视为接口类型是什么意思?

在TypeScrip中分配回调时,参数的分配方向与回调本身相反.为什么会这样呢?

与字符串文字模板的结果类型匹配的打字脚本

Express Yup显示所有字段的所有错误

角效用函数的类型推断

使用订阅时更新AG网格中的行

TypeScrip:来自先前参数的参数中的计算(computed)属性名称

限制返回联合的TS函数的返回类型

如何在typescript中为this关键字设置上下文

使用条件类型的类型保护

我可以使用typeof来强制执行某些字符串吗

在正常函数内部调用异步函数

声明遵循映射类型的接口

Typescript将键数组映射到属性数组

为什么我的函数arg得到类型为Never?

如何创建由一个帐户签名但使用另一个帐户支付的Hedera交易

我的类型谓词函数不能像我预期的那样工作.需要帮助了解原因

什么';是并类型A|B的点,其中B是A的子类?

有没有一种简单的方法可以访问Keyboard Shortcuts JSON文件中列出的每个命令的显示名称(标题)?

如果父级被删除或删除,如何自动删除子级?