能否直接从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
相关产品推荐
相关产品推荐

