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

能否直接从PropTypes shape推导TypeScript类型?

直接从PropTypes.shape推导TypeScript类型的优雅方案

问题根源

PropTypes.InferProps的设计目标是处理属性名到验证器的映射对象(比如你第一个例子里的{ id: PropTypes.number }),而PropTypes.shape()返回的是一个单个对象验证器(包含isRequired等方法的对象),直接将其传入InferProps会导致类型推导错误,得到的是验证器自身的类型而非目标属性类型。

优雅解决方案

利用TypeScript的条件类型和类型推断,直接从shape返回的验证器中提取内部的属性类型,无需拆分shape参数为单独常量。

方法1:自定义类型工具(复用性高)

import PropTypes from 'prop-types';

// 定义类型工具,提取验证器对应的属性类型
type InferShapeProps<T extends PropTypes.Validator<any>> = 
  T extends PropTypes.Validator<infer P> ? P : never;

// 你的shape验证器
const propsShape = PropTypes.shape({
  id: PropTypes.number,
  nested: PropTypes.shape({
    name: PropTypes.string
  })
});

// 直接推导类型
type PropsFromShape = InferShapeProps<typeof propsShape>;

// 测试使用
const y: PropsFromShape = { id: 123, nested: { name: "test" } };
const z = y.id; // 类型为 number | null | undefined
const nestedName = y.nested?.name; // 类型为 string | null | undefined

方法2:内联类型推断(更简洁)

如果不需要复用类型工具,可以直接内联推断逻辑:

import PropTypes from 'prop-types';

const propsShape = PropTypes.shape({
  id: PropTypes.number,
  nested: PropTypes.shape({
    name: PropTypes.string
  })
});

type PropsFromShape = typeof propsShape extends PropTypes.Validator<infer P> ? P : never;

// 测试使用
const y: PropsFromShape = { id: 456 };
console.log(y.id); // 类型正确

原理说明

PropTypes.shape()返回的Validator类型内部已经包含了其验证的对象类型信息,通过T extends PropTypes.Validator<infer P>可以提取出这个隐藏的P类型,也就是我们需要的属性结构类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 13:51:10