连接的组件作为子类型(TypeScript,ReactJS。React-redux)

时间:2018-10-31 13:51:55

标签: typescript react-redux

具有组件Translate和Text,并且想要将Translate定义为Text的子代,但是Translate与商店有联系,并且存在问题(我不明白为什么)。

翻译组件

import * as React from 'react'
import {connect} from 'react-redux'
import appState from '../store/types/appState'

type TranslateProps = {
  translations?: string[]
  keyString: string
}

class Translate extends React.Component<TranslateProps, any> {
  public render() {
    return (
      <React.Fragment>
        {this.translateString(this.props.keyString)}
      </React.Fragment>
    )
  }

  private translateString(key: string) {
    return this.props.translations[key] ? this.props.translations[key] : key
  }
}

const mapStateToProps = (state: appState) => ({translations: state.translations})

export default connect(mapStateToProps)(Translate)

文本组件

import * as React from 'react'
import Translate from './Translate'

type TextProps = {
  children: React.ReactElement<Translate> | React.ReactElement<Translate>[]
}

class Text extends React.Component<TextProps, any> {
  public render() {
    return (
      <StyledText>
        {this.props.children}
      </StyledText>
    )
  }
}

export default Text

我有一个编译错误:TS2304找不到名称“翻译”

我的tsconfig:

{
  "compilerOptions": {
    "baseUrl": ".",
    "lib": ["es2015", "es2016", "DOM"],
    "outDir": "./dist/",
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "moduleResolution": "node",
    "jsx": "react"
  },
  "typeRoots": [
    "node_modules/@types"
  ],
  "types": [
    "core-js",
    "webpack"
  ],
  "exclude": [
    "node_modules"
  ],
  "compileOnSave": true,
  "allowJs": true
}

任何未连接到存储的组件都不会出现此异常,而总是出现的则不会。哪里有问题?

1 个答案:

答案 0 :(得分:0)

对于原始的Translate组件类,Translate作为值引用该类本身,而Translate作为类型引用该类的实例类型。相反,connect返回新的组件类作为值,而connect的结果不能用作类型。默认的导出会使事情变得有些模糊。为了使问题更清楚,假设您写了:

const Translate2 = connect(mapStateToProps)(Translate);
type TextProps = {
  children: React.ReactElement<Translate2> | React.ReactElement<Translate2[]>;
}

Translate2只是一个值,不是类型。

如果您确实想要连接的组件的实例类型,则可以使用InstanceType<typeof Translate>。但是,React.ReactElement的type参数应该是组件的props类型(即TranslateProps),而不是组件实例类型。因此,导入TranslateProps并代替Translate使用它会更正确。但是,完全声明children道具的类型似乎没有什么好处(相对于依赖默认的ReactNode而言),因为:

  1. 您没有在实现中利用类型信息。
  2. 在呼叫站点,所有JSX元素的类型均为JSX.Element,它扩展了React.ReactElement<any>,可以为任何React.ReactElement<T>分配给T,而与实际的组件类型无关。 JSX元素。因此,您正在检查children是一个JSX元素还是一个JSX元素数组(与其他类型的ReactNode相反,例如字符串),但是您没有得到任何关于组件类型的检查是正确的。

因此,最好的解决方案可能就是从children中删除TextProps的声明。