TypeScript递归类型TPermissionQuery为何混入()=>boolean类型?
问题原因与解决方案
问题根源:Primitives类型未包含boolean
你定义的Primitives只覆盖了string | number | symbol,但boolean不在这个集合里。当Tree是boolean类型(比如示例里的message: true)时,会进入递归的对象遍历分支——而keyof boolean会拿到布尔包装对象原型上的方法(比如valueOf、toString),这些方法的类型是函数(比如() => boolean)。递归处理这些函数类型时,最终会让TPermissionQuery的返回值混入函数类型,触发rest参数必须是数组类型的报错。
为什么空对象时正常?
当message设为空对象{}时,keyof {}是never,遍历never不会生成任何属性分支,递归到空对象时直接终止,所以返回的类型只有预期的路径数组(['chat'] | ['chat', 'message']),没有多余的函数类型。
修复方案
把boolean加入到Primitives类型中,让布尔值触发递归终止条件:
type Primitives = string | number | symbol | boolean export type TPermissionQuery<Tree, Cache extends Array<Primitives> = []> = Tree extends Primitives ? Cache : { [Prop in keyof Tree]: [...Cache, Prop] | TPermissionQuery<Tree[Prop], [...Cache, Prop]> }[keyof Tree]
这样遇到boolean类型的属性值时,会直接返回当前的路径数组,不会继续遍历其原型方法,也就不会混入函数类型了。
内容的提问来源于stack exchange,提问作者monesles
相关产品推荐
相关产品推荐

