我有一个看起来像这样的组件:
- 它有一个带有"alerts"属性的接口
- 它连接到Redux并从道具中获得"警报">
interface IAlert {
alerts: { id: string; type: string; msg: string }[];
}
const Alert: FC<IAlert> = ({ alerts }) => {
return (
//does something with alerts
);
};
Alert.propTypes = {
alerts: PropTypes.array.isRequired
};
const mapStateToProps = (state: any): object => ({
alerts: state.alerts
});
export default connect(mapStateToProps, {})(Alert);
问题是:当我将这个组件(创建警报(导入另一个组件时,我会得到这个:
Property 'alerts' is missing in type '{}' but required in type 'Pick<IAlert, "alerts">'.ts(2741)
我不想将"警报"传递到导入的elemnt中,只想从Redux获得它。
谢谢你的帮助!
像@Jannis的答案中那样使用useSelector
钩子可以更容易地获得typescript支持。
您可以使用connect
进行正确的键入。这里没有得到它的原因是mapStateToProps
函数的类型不正确。
const mapStateToProps = (state: any): object => ({
alerts: state.alerts
});
connect
使得组件的连接版本不再需要由mapStateToProps
或mapDispatchToProps
添加的道具但是那些是什么道具。mapStateToProps
的类型定义并没有说它返回一个道具alerts
。它只是返回object
。
返回IAlert
会使您的错误消失,因为现在connect
知道已经提供了alerts
道具。
const mapStateToProps = (state: any): IAlert => ({
alerts: state.alerts
});
如果您的state
而不是any
有一个合适的类型,那么您根本不需要任何返回类型。对于这个特定的组件,IAlert
道具类型实际上描述了所需的状态和返回。
const mapStateToProps = (state: IAlert) => ({
alerts: state.alerts
});
但通常情况下,您希望从您的存储或reducer中获取状态类型,如这里所述。
export type RootState = ReturnType<typeof rootReducer>
export type RootState = ReturnType<typeof store.getState>
您需要在useSelector
中使用RootState
,但有一个有用的快捷方式,不需要每次使用都分配类型。您可以创建自己的类型化版本的useSelector
钩子,如下所述。
import { TypedUseSelectorHook, useSelector } from 'react-redux'
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector
所以现在您的组件不需要任何道具,并且alerts
变量的类型是基于状态的类型已知的
export default () => {
const alerts = useAppSelector(state => state.alerts);
return (
//does something with alerts
);
};