我发现在HOC中包装组件不会返回任何类型的注释。
简短的例子:
组件/按钮/ index.js
// @flow
import * as React from 'react'
import { withRouter } from 'react-router-dom'
import styled from 'styled-components'
const Wrapper = styled.button`
background-color: transparent;
`
type Props = {
children?: React.Node,
history: Object,
target: String
}
const Button = (props: Props) => {
return <Wrapper onClick={() => { if (props.target) props.history.push(props.target) }}>{props.children}</Wrapper>
}
export default withRouter(Button)
但是在另一个组件中使用它时,VS Code不会提供有关我的Button组件的任何信息:
它应该是这样的:
那么我该如何编写那些类型注释?
这是我目前的解决方案,基于评论和一些研究(类型的交集):
// @flow
import * as React from 'react'
import { RouterHistory, withRouter } from 'react-router-dom'
import styled from 'styled-components'
import theme from 'themes/default'
type ButtonProps = {
children: React.Node,
target: string,
}
type Props = ButtonProps & RouterHistory
const Wrapper = styled.button`
background-color: transparent;
`
const Button = ({ children, history, target }: Props) => (
<Wrapper onClick={() => { history.push(target)}}>{children}</Wrapper>
)
const enhanced: typeof Button = withRouter(Button)
export default enhanced
我确信有更好的解决方案,但如果没有输入类型,VS代码将不会显示除import Button
之外的任何提示。
答案 0 :(得分:2)
我猜Props
的类型是错误的。使用flow-typed的类型定义,ContextRouter
是withRouter
HOC提供的其他道具的类型。
import type { ContextRouter } from 'react-router';
type Props = ButtonProps & ContextRouter;
我在REPL上发了an example。
替代方法
HOC很难输入,因为流量需要从history
的道具中减去 Button
等。另一种选择是"render props" pattern。流程进行类型检查要容易得多,因为它不需要减法。
幸运的是,withRouter
只是Route
组件的一个薄包装,需要render
道具。
如果您使用Route
,则可以直接使用ButtonProps
,以便流程更容易理解。
type ButtonProps = {
children: React.Node,
target: string,
}
const Button = ({ children, target }: ButtonProps) => (
<Route
render={({ history }) => (
<button onClick={() => { history.push(target) }}>{children}</button>
)}
/>
)
export default Button
我还用REPL做了a working example with render prop。