- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
编辑:
请注意,不正确的构造函数是由 IntelliJ IDEA 生成的。现在已修复此问题,请参阅:https://youtrack.jetbrains.com/issue/WEB-35178
我正在考虑在我的应用程序中使用 Material-UI,但我在将 withStyles
样式解决方案与 TypeScript 结合使用时遇到了一些问题。
我正在尝试基于 Popper documentation 制作我自己的小包装器组件.
问题是,如果我按照我习惯的方式明确定义一个构造函数(下面代码中的 (B)
),那么这一行:
export default withStyles(styles)(HelpComponent);
给出这个错误:
ERROR in [at-loader] ./src/main/ts/screen/keyword/HelpComponent.tsx:150:35
TS2345: Argument of type 'typeof HelpComponent' is not assignable to parameter of type 'ComponentType<never>'.
Type 'typeof HelpComponent' is not assignable to type 'StatelessComponent<never>'.
Type 'typeof HelpComponent' provides no match for the signature '(props: never, context?: any): ReactElement<any> | null'.
我能够完成这项工作的唯一方法是省略显式构造函数并将状态定义为字段(下面代码中的 (A)
)。
当我使用 withStyles
时,有没有办法以正常方式声明构造函数?
其实我不介意像这样直接设置状态,它的样板少了一点。通过这种方式在构造函数外部初始化状态,我是否放弃了任何东西?
最终,我只是不明白 TypeScript 错误消息 - 任何人都可以解释它想表达的意思吗?
import {
createStyles,
Paper,
Popper,
Theme,
WithStyles,
withStyles
} from '@material-ui/core';
import * as React from 'react';
import {ReactNode, SyntheticEvent} from 'react';
import {EventUtil} from "appUtil/EventUtil";
import {WarningSvg} from "component/svg-icon/WarningSvg";
let log = require("log4javascript").getLogger("HelpComponent");
export interface HelpComponentProps extends WithStyles<typeof styles> {
children:ReactNode;
}
export interface HelpComponentState {
open:boolean;
arrowRef?: HTMLElement;
}
class HelpComponent extends React.Component<HelpComponentProps, HelpComponentState> {
helpRef!: HTMLElement;
// (A)
state = {open: false, arrowRef: undefined};
// (B)
// constructor(props: HelpComponentProps, context: HelpComponentState){
// super(props, context);
// this.state = {open: false, arrowRef: undefined};
// }
handleClick = (event:SyntheticEvent<any>) => {
EventUtil.stopClick(event);
this.setState({open: !this.state.open,});
};
handleArrowRef = (node:HTMLElement) => {
this.setState({
arrowRef: node,
});
};
render(){
const {classes} = this.props;
return <span ref={(ref)=>{if(ref) this.helpRef = ref}}>
<WarningSvg onClick={this.handleClick}/>
<Popper id={"help-popper"} className={classes.popper} transition
open={this.state.open} anchorEl={this.helpRef}
modifiers={{arrow:{enabled:true, element: this.state.arrowRef}}}
>
<span className={classes.arrow} ref={this.handleArrowRef}/>
<Paper className={classes.paper}>{this.props.children}</Paper>
</Popper>
</span>;
}
}
const styles = (theme: Theme) => createStyles({
root: {
flexGrow: 1,
},
scrollContainer: {
height: 400,
overflow: 'auto',
marginBottom: theme.spacing.unit * 3,
},
scroll: {
position: 'relative',
width: '230%',
backgroundColor: theme.palette.background.paper,
height: '230%',
},
legend: {
marginTop: theme.spacing.unit * 2,
maxWidth: 300,
},
paper: {
maxWidth: 400,
overflow: 'auto',
},
select: {
width: 200,
},
popper: {
zIndex: 1,
'&[x-placement*="bottom"] $arrow': {
top: 0,
left: 0,
marginTop: '-0.9em',
width: '3em',
height: '1em',
'&::before': {
borderWidth: '0 1em 1em 1em',
borderColor: `transparent transparent ${theme.palette.common.white} transparent`,
},
},
'&[x-placement*="top"] $arrow': {
bottom: 0,
left: 0,
marginBottom: '-0.9em',
width: '3em',
height: '1em',
'&::before': {
borderWidth: '1em 1em 0 1em',
borderColor: `${theme.palette.common.white} transparent transparent transparent`,
},
},
'&[x-placement*="right"] $arrow': {
left: 0,
marginLeft: '-0.9em',
height: '3em',
width: '1em',
'&::before': {
borderWidth: '1em 1em 1em 0',
borderColor: `transparent ${theme.palette.common.white} transparent transparent`,
},
},
'&[x-placement*="left"] $arrow': {
right: 0,
marginRight: '-0.9em',
height: '3em',
width: '1em',
'&::before': {
borderWidth: '1em 0 1em 1em',
borderColor: `transparent transparent transparent ${theme.palette.common.white}`,
},
},
},
arrow: {
position: 'absolute',
fontSize: 7,
width: '3em',
height: '3em',
'&::before': {
content: '""',
margin: 'auto',
display: 'block',
width: 0,
height: 0,
borderStyle: 'solid',
},
},
});
export default withStyles(styles)(HelpComponent);
版本:
最佳答案
如果您查看 React.ComponentType
的定义:
type ComponentType<P = {}> = ComponentClass<P> | StatelessComponent<P>;
您尝试使用的替代方法是 ComponentClass
,它定义为:
interface ComponentClass<P = {}, S = ComponentState> extends StaticLifecycle<P, S> {
new (props: P, context?: any): Component<P, S>;
// ...
}
请注意,context
参数是可选的(?
标记)。问题在于构造函数的 context
参数不是可选的,因此 HelpComponent
与希望能够省略 context
的调用者不兼容> 争论。如果您将参数设为可选,错误应该会消失。
当 TypeScript 报告 typeof HelpComponent
is not assignable to the union type React.ComponentType
时,它会半任意地选择联合类型的一个成员来报告一个详细错误。不幸的是,它没有选择您想要的那个,因此错误消息不是很有用。
I actually don't mind setting the state directly like this, it's a bit less boilerplate. Am I giving up anything by initialising the state outside the constructor this way?
是的,通过覆盖 state
属性,您可能会无意中将其类型更改为与您传递给 React.Component
基的状态类型参数不同的东西类。
关于reactjs - typescript :为什么 Material-UI "withStyles()"不能使用显式构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52585706/
我已经写了并且 npm 发布了这个:https://github.com/justin-calleja/pkg-dependents 现在我正在用 Typescript 编写这个包:https://g
我有一个函数,我想在 TypeScript 中模拟它以进行测试。在我的测试中,我只关心 json和 status .但是,当使用 Jest 的 jest.spyOn 时我的模拟函数的类型设置为返回 h
我正在使用一个库 (Axios),它的包中包含 Typescript 声明。 我想声明一个将 AxiosResponse(在库的 .d.ts 文件中声明)作为参数的函数。我有以下内容: functio
我是 Typescript 的新手。我想使用 将一个 Typescript 文件加载到另一个 Typescript 文件中标签。 我做了一些事情,但它不起作用!请帮助我。 first.ts: imp
为什么我会收到下面屏幕截图中显示的错误? Atom 说我的 tsconfig.json“项目文件包含无效选项”用于 allowJs、buildOnSave 和 compileOnSave。 但是应该允
所以我正在创建一个 TypeScript 库,我可以轻松地将所有生成的 JS 文件编译成一个文件。有没有办法将所有 .ts 和 .d.ts 编译成一个 .ts 文件? 除了支持 JS 的版本(较少的智
Microsoft Research 提供了一种名为Safer TypeScript 的新 TypeScript 编译器变体: http://research.microsoft.com/en-us/
我需要这个来在单个文件中分发 TypeScript 中的库。有没有办法将多个 typescript 文件合并到(一个js文件+一个 typescript 定义)文件中? 最佳答案 要创建一个库,您可以
用例:我想知道一个函数在 typescript 中执行需要多少时间。我想为此目的使用装饰器。我希望装饰器应该返回时间以便(我可以进一步使用它),而不仅仅是打印它。 例如: export functio
我想检查一个类型是否可以为 null,以及它是否具有值的条件类型。 我尝试实现 type IsNullable = T extends null ? true : false; 但是好像不行 type
我的问题是基于这个 question and answer 假设我们有下一个代码: const myFn = (p: { a: (n: number) => T, b: (o: T) => v
我知道双重否定前缀,我知道 TypeScript 的单后缀(非空断言)。 但是这个双后缀感叹号是什么? /.*验证码为(\d{6}).*/.exec(email.body!!)!![1] 取自here
我正在使用以下文件结构在 Webstorm 中开发一个项目 | src | ... | many files | types | SomeInterface |
在 TypeScript 类中,可以为属性声明类型,例如: class className { property: string; }; 如何在对象字面量中声明属性的类型? 我试过下面的代码,但它
我正在寻找一种在不丢失推断类型信息的情况下将 TypeScript 中的文字值限制为特定类型的好方法。 让我们考虑一个类型Named,它保证有一个名字。 type Named = { name:
在 TypeScript 中,我想创建一个联合类型来表示属于一个或多个不同类型的值,类似于 oneOf在 OpenAPI或 JSON Schema .根据a previous answer on a
type Func = (foo:string) => void // function expression const myFunctionExpression:Func = function(f
假设我有一个联合类型,我正在使用类似 reducer 的 API 调用模式,看起来像这样: type Action = { request: { action: "create
我在 typescript 中有以下去抖功能: export function debounce( callback: (...args: any[]) => void, wait: numb
在 Vue3 的 defineComponent 函数中,第一个泛型参数是 Props,所以我在这里使用 Typescript 接口(interface)提供我的 props 类型。喜欢: expor
我是一名优秀的程序员,十分优秀!