React PropTypes 与 defaultProps 结合并在对象内部出现问题

问题描述 投票:0回答:1

在以下 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
键。

那么我该如何解决这个问题呢?

reactjs typescript eslint react-props typescript-eslint
1个回答
0
投票

正如 @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 的类型时,它会考虑默认值的形状。

© www.soinside.com 2019 - 2024. All rights reserved.