React Recompose 在 Props 上导致 Typescript 错误
React Recompose Causing Typescript Error On Props
我有一个非常基本的有状态组件,我在其中使用重组将多个 HOC 添加到我的组件(在我的示例中,为了简单起见,我只使用一个)。出于某种原因,打字稿给我一个关于我的道具进入我的组件的错误。我怎样才能摆脱这个错误?
这是我的代码:
import * as React from 'react';
import { connect } from 'react-redux';
import { compose } from 'recompose';
interface IStoreState {
readonly sessionState: {
authUser: { email: string; }
}
}
interface IAccountPageProps {
authUser: { email: string }
}
const AccountPage = ({ authUser }: IAccountPageProps ) =>
<div>
<h1>Account: {authUser.email}</h1>
</div>
const mapStateToProps = (state: IStoreState) => ({
authUser: state.sessionState.authUser,
});
export default compose(
connect(mapStateToProps)
)(AccountPage);
我得到的错误是:
Argument of type '({ authUser }: IAccountPageProps) => Element' is not assignable to parameter of type 'ComponentType<{}>'.
Type '({ authUser }: IAccountPageProps) => Element' is not assignable to type 'StatelessComponent<{}>'.
Types of parameters '__0' and 'props' are incompatible.
Type '{ children?: ReactNode; }' is not assignable to type 'IAccountPageProps'.
Property 'authUser' is missing in type '{ children?: ReactNode; }'.
如果我不使用重组而是写
export default connect(mapStateToProps)(AccountPage)
我没有收到任何错误。
The current typing of compose
没什么用。如果要使用 compose
,则必须手动指定原始组件和最终组件的 props
类型,并且不会检查您指定的类型是否与您传递的高阶组件列表相匹配:
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps)
)(AccountPage);
我建议不要在 TypeScript 中使用 compose
。
compose 的类型允许您指定生成的组件的类型以及可以调用它的组件的类型,因此这将避免错误:
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps)
)(AccountPage);
不幸的是,compose 没有做任何事情来确保传递给它的函数的类型安全或兼容性。
因此,例如,即使它显然无效,也不会产生输入错误:
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps),
() => 'compose typing allows any function'
)(AccountPage);
嵌套 HOC 调用更安全:
export default
connect(mapStateToProps)(
firstHoc(
secondHoc(
AccountPage
)
)
);
我发现的最佳解决方案是重新断言类型,以便您也获得 connect
的类型(包括可用于轻松测试的 .WrappedComponent
),否则它默认为 React.ComponentClass<{}, any>
,这是不正确的,并且根据上面 @Matt 的示例不提供有关组件的信息。
使用您的示例,请参阅:
import React, { SFC } from 'react';
import { connect, ConnectedComponentClass } from 'react-redux';
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps)
)(AccountPage) as ConnectedComponentClass<SFC<IAccountPageProps>, {}>
现在,当您在别处使用该组件时,返回的组件可以正确输入连接包装器 ConnectedComponentClass<React.StatelessComponent<IAccountPageProps>, {}>
,现在您还可以访问 connectedComponent 值,例如 .WrappedComponent
.
ConnectedComponentClass
是 react-redux 的输入,它是连接组件的结束类型。在一个完美的世界中,这不是必需的,但它确实有效。
我有一个非常基本的有状态组件,我在其中使用重组将多个 HOC 添加到我的组件(在我的示例中,为了简单起见,我只使用一个)。出于某种原因,打字稿给我一个关于我的道具进入我的组件的错误。我怎样才能摆脱这个错误?
这是我的代码:
import * as React from 'react';
import { connect } from 'react-redux';
import { compose } from 'recompose';
interface IStoreState {
readonly sessionState: {
authUser: { email: string; }
}
}
interface IAccountPageProps {
authUser: { email: string }
}
const AccountPage = ({ authUser }: IAccountPageProps ) =>
<div>
<h1>Account: {authUser.email}</h1>
</div>
const mapStateToProps = (state: IStoreState) => ({
authUser: state.sessionState.authUser,
});
export default compose(
connect(mapStateToProps)
)(AccountPage);
我得到的错误是:
Argument of type '({ authUser }: IAccountPageProps) => Element' is not assignable to parameter of type 'ComponentType<{}>'.
Type '({ authUser }: IAccountPageProps) => Element' is not assignable to type 'StatelessComponent<{}>'.
Types of parameters '__0' and 'props' are incompatible.
Type '{ children?: ReactNode; }' is not assignable to type 'IAccountPageProps'.
Property 'authUser' is missing in type '{ children?: ReactNode; }'.
如果我不使用重组而是写
export default connect(mapStateToProps)(AccountPage)
我没有收到任何错误。
The current typing of compose
没什么用。如果要使用 compose
,则必须手动指定原始组件和最终组件的 props
类型,并且不会检查您指定的类型是否与您传递的高阶组件列表相匹配:
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps)
)(AccountPage);
我建议不要在 TypeScript 中使用 compose
。
compose 的类型允许您指定生成的组件的类型以及可以调用它的组件的类型,因此这将避免错误:
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps)
)(AccountPage);
不幸的是,compose 没有做任何事情来确保传递给它的函数的类型安全或兼容性。
因此,例如,即使它显然无效,也不会产生输入错误:
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps),
() => 'compose typing allows any function'
)(AccountPage);
嵌套 HOC 调用更安全:
export default
connect(mapStateToProps)(
firstHoc(
secondHoc(
AccountPage
)
)
);
我发现的最佳解决方案是重新断言类型,以便您也获得 connect
的类型(包括可用于轻松测试的 .WrappedComponent
),否则它默认为 React.ComponentClass<{}, any>
,这是不正确的,并且根据上面 @Matt 的示例不提供有关组件的信息。
使用您的示例,请参阅:
import React, { SFC } from 'react';
import { connect, ConnectedComponentClass } from 'react-redux';
export default compose<IAccountPageProps, {}>(
connect(mapStateToProps)
)(AccountPage) as ConnectedComponentClass<SFC<IAccountPageProps>, {}>
现在,当您在别处使用该组件时,返回的组件可以正确输入连接包装器 ConnectedComponentClass<React.StatelessComponent<IAccountPageProps>, {}>
,现在您还可以访问 connectedComponent 值,例如 .WrappedComponent
.
ConnectedComponentClass
是 react-redux 的输入,它是连接组件的结束类型。在一个完美的世界中,这不是必需的,但它确实有效。