我希望能够做这样的事情:
import Form as React.Component<IFormProps> from './Form';
这样我就可以使用组件了,它将需要在 IFormProps 界面中定义的道具。
我正在尝试执行此操作,因为我的Form组件使用redux-form
和redux
,并且两个装饰器根本不适合我。我花了很多时间来搜索有关如何执行此操作的示例,但是没有任何效果。这是我的Form导出的样子,因为其他任何操作都无法完成。
export default connect(
mapStateToProps,
mapDispatchToProps,
)((reduxForm as any)(formConfig)(Form)) as any;
真的不应该那么难,我在Form组件内部有一个IFormProps接口,我只想让打字稿识别其中的必需道具。
编辑: 根据要求,我将添加有关组件外观的更多信息,但请注意,就键入而言,组件相当复杂。要使这些连接和redux形式的装饰器正常工作,我遇到了很多麻烦,我不得不做很多解决方法。而且浪费了很多时间。归根结底,我只需要针对IFormProps进行验证的组件,我什至不在乎装饰器是否不能一起工作。对于这件事,在这里或谷歌上似乎在这方面没有太多帮助。无论如何,下面有更多代码:
Form.tsx
import * as React from 'react';
import {
clearForm,
doFormSubmit,
getFormRelatedValues,
IClearForm,
IDoFormSubmit,
IGetFormRelatedValues,
ISearchFormRelatedValues,
IUploadFile,
searchFormRelatedValues,
uploadFile,
} from '../actions/formActions';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { reduxForm, SubmissionError } from 'redux-form';
const { Component } = React;
function onSubmitFail(errors: IDCRA.IGenericObj,
dispatch: IDCRA.IDispatch,
submitError: IDCRA.IGenericObj,
props: IFromProps) {
// Something....
}
function scrollToFirstError() {
// Something else....
}
const formConfig = {
onSubmitFail: (
errors: IDCRA.IGenericObj,
dispatch: IDCRA.IDispatch,
submitError: IDCRA.IGenericObj,
props: IFromProps,
) => scrollToFirstError(errors, props),
returnRejectedSubmitPromise: true,
validate: someValidate,
};
declare interface IFromProps {
// setFormWarningMessage?: (msg: string) => void;
appContext?: string;
asyncBlurFields?: string[];
asyncValidate?: IAsyncValidate;
change?: IDCRA.IChangeFieldValue;
clearFormConnect?: IClearForm;
doFormSubmitConnect?: IDoFormSubmit;
error?: string;
fields: { [key: string]: IDCRA.IField };
firstPage: boolean;
form: string;
formObj: IDCRA.IForm;
formPageIdentifier: string;
getFormRelatedValuesConnect?: IGetFormRelatedValues;
goToPrevPage?: () => any;
handleSubmit?: (fn: (values: IDCRA.IGenericObj, dispatch: IDCRA.IDispatch) => any) => any;
i18n?: IDCRA.IGenericObj;
initialValues?: IDCRA.IGenericObj;
invalid?: boolean;
isCreateMode: boolean;
lang: string;
lastPage: boolean;
onSubmitSuccess: (response: IDCRA.ISaveCardResponseObj) => any;
ownerIdentifier: string;
partialSave?: boolean;
pristine?: boolean;
rows: string[][];
searchFormRelatedValuesConnect?: ISearchFormRelatedValues;
submitButtonLabel?: string;
submitFailed?: boolean;
submitting?: boolean;
untouch?: IDCRA.IUntouchField;
uploadFileConnect?: IUploadFile;
waitForEvent?: boolean;
}
class Form extends Component<IFromProps, {}> {
constructor(props: IFromProps) {
super(props);
this.handleFormSubmit = this.handleFormSubmit.bind(this);
}
handleFormSubmit(values: IDCRA.IGenericObj, dispatch: IDCRA.IDispatch) {
// Handles form submit....
}
render() {
// Props are consumed here and used to build the form
const {handleSubmit, identifier} = this.props;
return (
<div className="form" id={`form-container-${identifier}`}>
<form onSubmit={handleSubmit(this.handleFormSubmit)}>
<div className="card bg-default">
{/* my form parts are here, not important */}
</div>
</form>
</div>
);
}
}
function mapStateToProps(state: IDCRA.IAppState) {
return {
appContext: state.appCoreData.appCoreData.appContext,
i18n: state.appCoreData.appCoreData.i18n,
};
}
// I have to use my own dispatch type because by default I get errors...
// It's really hard to debug these deply nested TS errors, the messages are cryptic and could be coming from multple source
function mapDispatchToProps(dispatch: IDCRA.IDispatch) {
return bindActionCreators(
{
// setFormWarningMessage,
clearFormConnect: clearForm,
doFormSubmitConnect: doFormSubmit,
getFormRelatedValuesConnect: getFormRelatedValues,
searchFormRelatedValuesConnect: searchFormRelatedValues,
uploadFileConnect: uploadFile,
},
dispatch,
);
}
// Decorate the form component
export default connect(
mapStateToProps,
mapDispatchToProps,
)((reduxForm as any)(formConfig)(Form)) as any;
如果我从连接中删除语句中的 any 强制转换,这是我得到的错误:
TS2345: Argument of type 'typeof Form' is not assignable to parameter of type 'ComponentType<IFromProps & InjectedFormProps<{ [x: string]: any; }, IFromProps>>'.
Type 'typeof Form' is not assignable to type 'StatelessComponent<IFromProps & InjectedFormProps<{ [x: string]: any; }, IFromProps>>'.
Type 'typeof Form' provides no match for the signature '(props: IFromProps & InjectedFormProps<{ [x: string]: any; }, IFromProps> & { children?: ReactNode; }, context?: any): ReactElement<any>'.
如果我只在reduxForm装饰器上保留any,则会出现此错误。
TS2339: Property 'fields' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, ComponentState, any>> & Readonly<{ children?: ReactNode; }> & Readonly<{}>'.
对于它的价值,我并不期望任何人能够解决这些错误,只是发生了太多的事情。我本人已经花了几个小时试图消除错误,这只是一场just鼠游戏。
因此,最终,如果我可以简单地覆盖TS认为导出的组件是什么,我会很高兴的。
答案 0 :(得分:1)
好的,我这样做可以使它工作:
class Form extends Component<InjectedFormProps & IFromProps, {}> .....
然后像这样导出:
export default connect<{}, {}, IFromProps, {}>(
mapStateToProps,
mapDispatchToProps,
)(reduxForm(formConfig)(Form));
现在我的组件可以验证正确的道具了!