如何为将字符串作为键并将 React SFC 作为值的对象包装器定义 TypeScript 类型?
How to define TypeScript type for object wrapper that has string as a key & React SFC as a value?
以下是Form组件
import React from 'react';
import { Elements } from '@helpers/ImportProxy';
import { mockApi } from '@constants/api';
type Props = {
// formValues: any
};
type MapKindToComponentT = {
[key: string]: React.SFC
}
/** @component */
export const Form: React.SFC<Props> = __props => {
const renderQuestions = () =>
mockApi.map(
(question, index): React.ReactElement | undefined => {
const mapKindToComponent: MapKindToComponentT = {
radio: Elements.RadioElement,
text: Elements.InputElement,
email: Elements.InputElement,
url: Elements.InputElement,
checkbox: Elements.CheckBoxElement,
dropdown: Elements.SelectElement,
textarea: Elements.TextareaElement,
};
if(mapKindToComponent[question.kind]) {
const Element = mapKindToComponent[question.kind];
return <Element key={index} question={question} />;
}
}
);
return (
<form>
{renderQuestions()}
<div>
<button type="submit">Submit</button>
</div>
</form>
);
};
export default Form;
mapKindToComponent
每个key的值是React函数式组件。
以下是我为它当前定义的类型得到的错误。适用于 any
.
Type error: Type 'FunctionComponent' is not assignable to type
'FunctionComponent<{}>'. Types of property 'propTypes' are
incompatible.
Type 'WeakValidationMap | undefined' is not assignable to type 'WeakValidationMap<{}> | undefined'.
Type 'WeakValidationMap' is not assignable to type 'WeakValidationMap<{}>'.
Type '{}' is not assignable to type 'Props'. TS2322
解决方案
明确表示 MapKindToComponentT
接受任何类型的函数组件。
type MapKindToComponentT = {
[key: string]: React.SFC<any>
}
说明
@types/react
中定义的 React.SFC
的默认类型参数(描述 Props
的参数)是 {}
。
type SFC<P = {}> = FunctionComponent<P>;
如果一个组件需要一些更精确的类型作为它的 props,例如 { foo: string }
:
declare const SomeComponent: React.SFC<{ foo: string }>;
这样的组件将无法分配给 React.SFC
。
const MyComponent: React.SFC = SomeComponent; // ⛔️ Compile-time error
const MyComponent: React.SFC<any> = SomeComponent; // ✅ OK
以下是Form组件
import React from 'react';
import { Elements } from '@helpers/ImportProxy';
import { mockApi } from '@constants/api';
type Props = {
// formValues: any
};
type MapKindToComponentT = {
[key: string]: React.SFC
}
/** @component */
export const Form: React.SFC<Props> = __props => {
const renderQuestions = () =>
mockApi.map(
(question, index): React.ReactElement | undefined => {
const mapKindToComponent: MapKindToComponentT = {
radio: Elements.RadioElement,
text: Elements.InputElement,
email: Elements.InputElement,
url: Elements.InputElement,
checkbox: Elements.CheckBoxElement,
dropdown: Elements.SelectElement,
textarea: Elements.TextareaElement,
};
if(mapKindToComponent[question.kind]) {
const Element = mapKindToComponent[question.kind];
return <Element key={index} question={question} />;
}
}
);
return (
<form>
{renderQuestions()}
<div>
<button type="submit">Submit</button>
</div>
</form>
);
};
export default Form;
mapKindToComponent
每个key的值是React函数式组件。
以下是我为它当前定义的类型得到的错误。适用于 any
.
Type error: Type 'FunctionComponent' is not assignable to type 'FunctionComponent<{}>'. Types of property 'propTypes' are incompatible. Type 'WeakValidationMap | undefined' is not assignable to type 'WeakValidationMap<{}> | undefined'. Type 'WeakValidationMap' is not assignable to type 'WeakValidationMap<{}>'. Type '{}' is not assignable to type 'Props'. TS2322
解决方案
明确表示 MapKindToComponentT
接受任何类型的函数组件。
type MapKindToComponentT = {
[key: string]: React.SFC<any>
}
说明
@types/react
中定义的 React.SFC
的默认类型参数(描述 Props
的参数)是 {}
。
type SFC<P = {}> = FunctionComponent<P>;
如果一个组件需要一些更精确的类型作为它的 props,例如 { foo: string }
:
declare const SomeComponent: React.SFC<{ foo: string }>;
这样的组件将无法分配给 React.SFC
。
const MyComponent: React.SFC = SomeComponent; // ⛔️ Compile-time error
const MyComponent: React.SFC<any> = SomeComponent; // ✅ OK