在以下 React 17.0.2 示例中:
// Container.tsx
const InfoPropType = {
legend: PropTypes.string.isRequired,
value: PropTypes.number,
};
const ContainerPropTypes = {
config: PropTypes.shape({
c1: PropTypes.shape(InfoPropType).isRequired,
}),
};
type ContainerType = InferProps<typeof ContainerPropTypes>;
const ContainerDefaultProps = { config: { c1: { value: 1 } } };
const Container = (props: ContainerType & typeof ContainerDefaultProps): JSX.Element => {
const { config: cConfig } = props;
return (
<div>
{cConfig.c1.legend} has {cConfig.c1.value}
</div>
);
};
Container.propTypes = ContainerPropTypes;
Container.defaultProps = ContainerDefaultProps;
// App.tsx
type ConfigType = { c1: { legend: string; value?: number; } };
const App = (): JSX.Element => {
const aConfig: ConfigType = { c1: { legend: 'l1' } };
return (<Container config={aConfig} />);
^----^ /* property with lint error */
};
export default App;
我在
config
线上收到 <Container config={aConfig} />
的错误:
Type 'ConfigType' is not assignable to type 'InferPropsInner<Pick<{ c1: Validator<NonNullable<InferProps<{ legend: Validator<string>; value: Requireable<number>; }>>>; }, "c1">> & Partial<...> & { ...; }'.
Type 'ConfigType' is not assignable to type '{ c1: { value: number; }; }'.
The types of 'c1.value' are incompatible between these types.
Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
The expected type comes from property 'config' which is declared here on type 'IntrinsicAttributes & Pick<Pick<InferPropsInner<Pick<{ config: Requireable<InferProps<{ c1: Validator<NonNullable<InferProps<{ legend: Validator<string>; value: Requireable<number>; }>>>; }>>; }, never>> & Partial<...> & { ...; }, "config"> & Pick<...> & Pick<...>, never> & Partial<...> & Partial<...>'
对我来说基本上是:对象
aConfig
不能分配给属性config
,因为aConfig
的类型有一个可选键value
,而在预期类型中,value
键是必需的。
但情况并非如此,因为
Container.tsx
不需要 value
键。
那么我该如何解决这个问题呢?
正如 @jonrsharpe 提到的,这看起来像是 TypeScript 编译器问题。它与 TypeScript 对 React 组件中默认值的类型检查和类型推断有关。
在 Container.tsx 中,您定义了 ContainerDefaultProps,但没有
legend
的默认 prop 值,即使 InfoPropType
需要该值。
我认为这可以解决问题。
// Container.tsx
const ContainerDefaultProps = { config: { c1: { legend: '', value: 1 } }};
// App.tsx
const aConfig: ConfigType = { c1: { legend: 'l1', value: 0 } };};
还有更多内容:
在 React 中,当未提供或未定义 prop 时,默认 prop 值通常用作后备。当 TypeScript 根据默认 prop 值推断组件 prop 的类型时,它会考虑默认值的形状。