You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中React.PureComponent可选默认Props配置问题

给React PureComponent设置可选Props & 解决connect类型不匹配问题

当然可以给PureComponent设置可选props——你遇到的编译错误和Readonly无关,核心问题是组件的props接口和connect传递的props类型不匹配,另外你的接口里还有个小细节需要修正。

先修正接口里的类型错误

你的CounterProps里value?: string & number;这行有问题:string & number是never类型(没有值能同时是字符串和数字),应该改成你实际需要的类型,比如可选的数字:

interface CounterProps {
  incrementAsync(): void;
  increment(): void;
  decrement(): void;
  value?: number; // 改成可选数字,或者string | number如果需要支持两种类型
}

为什么connect会报错?

当你使用connect时,mapStateToProps返回的对象(比如{ value: number })和mapDispatchToProps返回的方法会合并成组件的props。如果mapStateToProps总是返回value(即value是必传的),但你的组件接口里value是可选的,TypeScript就会抛出类型不匹配的错误——这和PureComponent的Readonly属性无关,Readonly<P>只是禁止在组件内部修改props,完全允许存在可选键。

解决方案:让组件接口和connect提供的props匹配

根据你的业务场景,有两种处理方式:

方式1:如果value是必传的(mapStateToProps总是返回它)

直接把接口里的value改成必填项:

interface CounterProps {
  incrementAsync(): void;
  increment(): void;
  decrement(): void;
  value: number; // 去掉?,设为必填
}

方式2:如果value可能不存在,设置默认值

如果value可能从state里取不到,你可以在两个地方设置默认值:

  • 在组件里设置defaultProps:PureComponent完全支持defaultProps
  • 在mapStateToProps里处理默认值

示例代码如下:

import React from 'react';
import { connect } from 'react-redux';

// 修正后的接口
interface CounterProps {
  incrementAsync(): void;
  increment(): void;
  decrement(): void;
  value?: number;
}

class Counter extends React.PureComponent<CounterProps> {
  // 设置默认props
  static defaultProps: Partial<CounterProps> = {
    value: 0
  };

  render() {
    // 因为有defaultProps,这里可以安全地使用this.props.value
    return (
      <div>
        <button onClick={this.props.incrementAsync}>Increment after 1 second</button>{' '}
        <button onClick={this.props.increment}>Increment</button>{' '}
        <button onClick={this.props.decrement}>Decrement</button>
        <hr />
        <div>Clicked: {this.props.value} times</div>
      </div>
    );
  }
}

// 假设你的state结构
interface AppState {
  counter: number;
}

// mapStateToProps里处理默认值(可选,和defaultProps二选一或者结合使用)
const mapStateToProps = (state: AppState) => ({
  value: state.counter ?? 0 // 如果state.counter不存在,返回0
});

// mapDispatchToProps示例
const mapDispatchToProps = {
  increment: () => ({ type: 'INCREMENT' }),
  decrement: () => ({ type: 'DECREMENT' }),
  incrementAsync: () => ({ type: 'INCREMENT_ASYNC' })
};

// 现在connect不会报错了
export default connect(mapStateToProps, mapDispatchToProps)(Counter);

关于Readonly的误区

PureComponent的props类型是Readonly<{ children?: ReactNode }> & Readonly<P>,这里的Readonly只是把props对象变成只读的,不允许你在组件内部修改this.props的属性,但完全支持可选属性。比如Readonly<{ value?: number }>是完全合法的类型,这不是你报错的原因。

内容的提问来源于stack exchange,提问作者Michał Wojas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:16:31