使用Redux-Form与React-Redux连接时的TypeScript错误

Tom*_*ney 6 typescript reactjs redux redux-form react-redux

我爱上了TypeScript,直到我发现Redux-Form与React-Redux之间存在一些非常令人沮丧的不兼容性.

我的目标是reduxForm使用react-redux connect装饰器包装一个装饰组件- 这种模式在babel配置中一直对我有用,并且似乎遵循HOC方法.这是一个例子:

import * as React from 'react';
import { Dispatch } from 'redux';
import { connect } from 'react-redux';
import { reduxForm, Field, InjectedFormProps } from 'redux-form';

interface SampleFormData {
  username: string;
}

interface SampleFormProps {
  saveData: (data: SampleFormData) => void;
}

type AllSampleFormProps = SampleFormProps & InjectedFormProps<SampleFormData>;

const SampleForm: React.SFC<AllSampleFormProps> = (props) => (
  <form onSubmit={props.handleSubmit(props.saveData)}>
    <Field name="username" component="input" />
  </form>
);

const DecoratedSampleForm = reduxForm<SampleFormData>({ form: "sampleForm" })(SampleForm);

export default connect(
  () => ({}),
  (dispatch) => ({
    saveData: (data: SampleFormData) => dispatch({ type: "SAVE_DATA", data })
  })
)(DecoratedSampleForm);
Run Code Online (Sandbox Code Playgroud)

这是TypeScript抛出的错误:

> Argument of type 'DecoratedComponentClass<SampleFormData,
> Partial<ConfigProps<SampleFormData, {}>>>' is not assignable to
> parameter of type 'ComponentType<{ saveData: (data: SampleFormData) =>
> { type: string; data: SampleFormData; }; }>'.
> 
> Type 'DecoratedComponentClass<SampleFormData,
> Partial<ConfigProps<SampleFormData, {}>>>' is not assignable to type
> 'StatelessComponent<{ saveData: (data: SampleFormData) => { type:
> string; data: SampleFormData; };...'.
> 
> Type 'DecoratedComponentClass<SampleFormData,
> Partial<ConfigProps<SampleFormData, {}>>>' provides no match for the
> signature '(props: { saveData: (data: SampleFormData) => { type:
> string; data: SampleFormData; }; } & { children?: ReactNode; },
> context?: any): ReactElement<any>'.
Run Code Online (Sandbox Code Playgroud)

有没有人找到一个让react-redux接受这种DecoratedComponentClass类型的解决方案?我发现了一个使用"中间"组件的建议,但我没有设法让它与thunk动作一起使用.另外我发现这会产生更多的问题,而不是在键入表单的道具方面解决的问题.

Tom*_*ney 10

对于遇到此问题的任何人,我发现通过提供带有空TStatePropsTDispatchProps对象的connect语句,我能够解除错误.

interface SampleFormData {
  username: string;
}

interface SampleFormProps {
  saveData: (data: SampleFormData) => void;
}

type AllSampleFormProps = SampleFormProps & InjectedFormProps<SampleFormData>;

const SampleForm: React.SFC<AllSampleFormProps> = (props) => (
  <form onSubmit={props.handleSubmit(props.saveData)}>
    <Field name="username" component="input" />
  </form>
);

const DecoratedSampleForm = reduxForm<SampleFormData>({ form: "sampleForm" })(SampleForm);

export default connect<{},{}>(
  () => ({}),
  (dispatch) => ({
    saveData: (data: SampleFormData) => dispatch({ type: "SAVE_DATA", data })
  })
)(DecoratedSampleForm);
Run Code Online (Sandbox Code Playgroud)

这样做的一个缺点是它迫使我们盲目地提供连接道具,但我觉得这比写一个覆盖@types声明更优雅.

为了解决这个缺点,我能够通过提供连接正确的接口与空对象来验证类型; 但是,此方法只能临时完成以检查绑定,因为它不能解决DecoratedComponentClass错误.

export default connect<{}, SampleFormProps, InjectedFormProps<SampleFormData>>(
  () => ({}),
  (dispatch) => ({
    saveData: (data: SampleFormData) => dispatch({ type: "SAVE_DATA", data })
  })
)(DecoratedSampleForm);
Run Code Online (Sandbox Code Playgroud)