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

React 18 TypeScript中如何定义非可选的defaultProps

React函数组件中为必填Props设置默认值的正确姿势

在React + TypeScript的函数组件中,官方推荐通过函数参数默认值设置props默认值,但这种方式仅适用于标记为可选(?)的属性。如果想给必填Props设置默认值,同时避免将其设为可选(防止外部传入undefined或漏传值导致崩溃),可以用以下几种方案解决:


方案1:拆分内外Props类型

通过定义外部暴露的必填Props类型,以及内部组件接收的可选Props类型(结合默认参数),同时用类型断言让组件对外暴露正确的必填约束:

import React from 'react';

// 外部调用时必须遵守的Props:importantProp为必填,禁止传入undefined
interface RequiredProps {
  importantProp: string;
}

// 内部组件接收的Props:允许importantProp可选(因为有默认值兜底)
type InternalProps = Omit<RequiredProps, 'importantProp'> & Partial<Pick<RequiredProps, 'importantProp'>>;

// 组件对外暴露RequiredProps类型,内部使用InternalProps处理默认值
const ImportantComponent: React.FC<RequiredProps> = ({ importantProp = '默认值' }: InternalProps) => {
  return <div>{importantProp}</div>;
};

// 使用示例
const App = () => {
  return (
    <>
      <ImportantComponent /> {/* 正常,自动使用默认值 */}
      <ImportantComponent importantProp="自定义内容" /> {/* 正常 */}
      <ImportantComponent importantProp={undefined} /> {/* TS报错:undefined无法赋值给string */}
    </>
  );
};

方案2:使用函数重载

通过TypeScript的函数重载,明确组件的两种合法调用方式:不传目标Props(用默认值)、传合法的string值,直接禁止传入undefined的情况:

import React from 'react';

interface Props {
  importantProp: string;
}

// 重载1:不传importantProp,使用默认值
function ImportantComponent(): React.ReactElement;
// 重载2:传入合法的importantProp
function ImportantComponent(props: Props): React.ReactElement;

// 组件实现:接收可选的props,设置默认值
function ImportantComponent(props?: Partial<Props>) {
  const { importantProp = '默认值' } = props || {};
  return <div>{importantProp}</div>;
}

// 使用示例
const App = () => {
  return (
    <>
      <ImportantComponent /> {/* 正常 */}
      <ImportantComponent importantProp="自定义内容" /> {/* 正常 */}
      <ImportantComponent importantProp={undefined} /> {/* TS报错:无匹配的重载签名 */}
    </>
  );
};

方案3:自定义工具类型复用逻辑

如果多个组件或多个Props需要类似处理,可以自定义Defaultize工具类型,将指定的必填Props转为可选,同时保留其他必填项的约束:

import React from 'react';

// 自定义工具类型:将指定的必填属性转为可选,用于设置默认值
type Defaultize<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;

interface Props {
  importantProp: string;
  otherRequiredProp: number; // 其他必须传入的属性
}

// 组件接收处理后的Props,设置importantProp的默认值
const ImportantComponent = ({
  importantProp = '默认值',
  otherRequiredProp
}: Defaultize<Props, 'importantProp'>) => {
  return (
    <div>
      {importantProp} - {otherRequiredProp}
    </div>
  );
};

// 使用示例
const App = () => {
  return (
    <>
      {/* 必须传otherRequiredProp,importantProp可选 */}
      <ImportantComponent otherRequiredProp={123} /> {/* 正常,使用默认值 */}
      <ImportantComponent otherRequiredProp={456} importantProp="自定义内容" /> {/* 正常 */}
      <ImportantComponent otherRequiredProp={789} importantProp={undefined} /> {/* TS报错 */}
      <ImportantComponent /> {/* TS报错:缺少otherRequiredProp */}
    </>
  );
};

注意事项

  • 避免使用Component.defaultProps:官方已不推荐在函数组件中使用该方式,且结合TypeScript容易出现类型不一致问题。
  • 以上方案均保证:组件内部的importantProp始终为合法的string类型,外部调用时要么不传(用默认值),要么传合法的string,禁止传入undefined。

内容的提问来源于stack exchange,提问作者Kipnoedels

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:12:49