如何定义包含自身数组的PropTypes.exact/shape递归类型?
解决递归PropTypes.exact定义的引用错误问题
你遇到的是变量初始化顺序的问题:const声明的变量在完成初始化前无法被访问,而你在定义对象字面量的children属性时直接引用了还没初始化完成的StatusLogLineShape,所以触发了错误。下面是两种可行的解决办法:
方法一:拆分对象初始化步骤
先定义不含递归属性的基础对象,等变量完全初始化后再补充递归属性:
// 先定义基础属性 const statusLogLineBase = { dt: PropTypes.number.isRequired, indentLevel: PropTypes.number.isRequired, stat: PropTypes.number.isRequired, exp: PropTypes.boolean, msg: PropTypes.string.isRequired, }; // 补充递归的children属性,此时StatusLogLineShape已经可以被引用 export const StatusLogLineShape = PropTypes.exact(statusLogLineBase); statusLogLineBase.children = PropTypes.arrayOf(StatusLogLineShape);
注意这里要先把基础对象包装成exact类型得到StatusLogLineShape,再给基础对象添加children属性,这样children的类型校验会指向已经初始化完成的精确类型。
方法二:用函数延迟求值
利用PropTypes支持函数返回类型的特性,把递归引用放在函数里,这样函数会在类型校验阶段才执行,此时StatusLogLineShape已经完成初始化:
export const StatusLogLineShape = PropTypes.exact({ dt: PropTypes.number.isRequired, indentLevel: PropTypes.number.isRequired, stat: PropTypes.number.isRequired, exp: PropTypes.boolean, msg: PropTypes.string.isRequired, // 用函数返回递归类型,避免初始化阶段的引用 children: PropTypes.arrayOf(() => StatusLogLineShape), });
这种写法更简洁,不需要拆分对象结构,适合大多数场景。
内容的提问来源于stack exchange,提问作者Emma Leis
相关产品推荐
相关产品推荐

