在示例中如何键入Material-UI的`withStyles`装饰器的用法?

时间:2018-11-04 05:57:34

标签: typescript material-ui

我试图弄清楚如何注释以下样式的类型(我从纯JavaScript转换为TypeScript并添加了类型注释):

import * as React from 'react'
import { withStyles } from '@material-ui/core'

@withStyles(styles) // TYPE ERROR HERE
export default class App extends React.Component<{}, {}> {
    render(): JSX.Element {
        return (
            <div className="some-class"> Hello </div>
        )
    }
}

function styles() {
    return {
        // assume I need to use global styles, my actual project is more
        // complex and for some reasons I need to use global styles
        '@global': {
            '.some-class': {
                overflowX: 'hidden'
            },
        },
    }
}

我们如何键入?

起初,它给我一个错误,如:

        Types of property 'overflowX' are incompatible.
          Type 'string' is not assignable to type '"scroll" | "hidden" | "visible" | "auto" | "clip" | "-moz-initial" | "inherit" | "initial" | "revert" | "unset" | undefined'.

所以我将其更改为使用createStyles的以下内容:

import * as React from 'react'
import { withStyles, createStyles } from '@material-ui/core'

@withStyles(styles) // TYPE ERROR HERE
export default class App extends React.Component<{}, {}> {
    render(): JSX.Element {
        return (
            <div className="some-class"> Hello </div>
        )
    }
}

function styles() {
    return createStyles({
        // assume I need to use global styles, my actual project is more
        // complex and for some reasons I need to use global styles
        '@global': {
            '.some-class': {
                overflowX: 'hidden'
            },
        },
    })
}

现在我收到此错误:

tmp.tsx:5:1 - error TS1238: Unable to resolve signature of class decorator when called as an expression.
  Type 'ComponentClass<Pick<{}, never> & StyledComponentProps<"@global">, any>' is not assignable to type 'void | typeof App'.
    Type 'ComponentClass<Pick<{}, never> & StyledComponentProps<"@global">, any>' is not assignable to type 'typeof App'.
      Type 'Component<Pick<{}, never> & StyledComponentProps<"@global">, any, any>' is not assignable to type 'App'.
        Types of property 'render' are incompatible.
          Type '() => ReactNode' is not assignable to type '() => Element'.
            Type 'ReactNode' is not assignable to type 'Element'.
              Type 'undefined' is not assignable to type 'Element'.

5 @withStyles(styles) // TYPE ERROR HERE
  ~~~~~~~~~~~~~~~~~~~

在我实际的,更复杂的代码中,错误类似,关于无法匹配Component类型:

App.tsx:44:1 - error TS1238: Unable to resolve signature of class decorator when called as an expression.
  Type 'ComponentClass<Pick<AppProps, never> & StyledComponentProps<"@global">, any>' is not assignable to type 'void | typeof App'.
    Type 'ComponentClass<Pick<AppProps, never> & StyledComponentProps<"@global">, any>' is not assignable to type 'typeof App'.
      Type 'Component<Pick<AppProps, never> & StyledComponentProps<"@global">, any, any>' is not assignable to type 'App'.
        Property 'makeOnStatusWindowClick' is missing in type 'Component<Pick<AppProps, never> & StyledComponentProps<"@global">, any, any>'.

44 @withStyles(styles)
   ~~~~~~~~~~~~~~~~~~~

其中makeOnStatusWindowClick是我的组件类中定义的第一个方法。

2 个答案:

答案 0 :(得分:3)

Daniel链接说的Material UI文档

  

不幸的是,由于TypeScript装饰器的当前限制,withStyles(styles)不能用作TypeScript中的装饰器。

所以我可以通过做两件事使其工作:

  • createStyles函数的返回对象上使用styles(并且不要在函数上使用显式的返回类型定义,以便它使用由createStyles生成的返回类型定义)< / li>
  • withStyles用作装饰器而非
  • 使用WithStyles的自动检测类型,将styles用作道具

代码如下:

import * as React from 'react'
import { withStyles, WithStyles, createStyles } from '@material-ui/core'

interface Props extends WithStyles<typeof styles> {}

class App extends React.Component<Props, {}> {
    render(): JSX.Element {
        return (
            <div className="some-class"> Hello </div>
        )
    }
}

export default withStyles(styles)(App)

function styles() /*: do not put a return type here */ {
    return createStyles({
        // assume I need to use global styles, my actual project is more
        // complex and for some reasons I need to use global styles
        '@global': {
            '.some-class': {
                overflowX: 'hidden'
            },
        },
    })
}

答案 1 :(得分:1)

幸运的是,他们在https://material-ui.com/guides/typescript/

上有关于打字稿的详尽文档

此外,您没有提到自己遇到的错误,因此要知道出了什么问题很棘手

您的道具类型可能缺少classes字段