键入具有特定叶类型的嵌套对象

时间:2017-05-05 16:20:46

标签: typescript recursive-datastructures

我想要一个嵌套对象的类型,它们在它们的叶子上有一个特定的类型。

我希望这是正确的:

let a: Leaves<number> = {
    "foo": 1,
    "bar": {
        "baz": 2
    }
};

这就失败了:

let a: Leaves<number> = {
    "foo": 1,
    "bar": {
        "baz": 'something else' // Leaf of type string
    } 
};

我试过

export type Leaves<T> = {
    [P in keyof T]: T | Leaves<T>;
}

但是,根据该定义,这两个示例都会出现编译错误。第一个说Type '{ "foo": number; "bar": number; }' is not assignable to type 'number'.

有没有办法解决这个问题?

1 个答案:

答案 0 :(得分:1)

如果您需要具有任意键的节点的类型,以及值作为叶子或其他节点,indexable type是可行的方法:

export type Leaves<T> = {
    [n: string]: T | Leaves<T>
}

(顺便说一句,我宁愿称之为Node<T>,而不是Leaves<T>

这里的映射类型不合适,因为像这样的映射类型

{
    [P in keyof T]: T | Leaves<T>;
}

只能包含T所拥有的属性 - 这就是[P in keyof T]:所说的内容。当Tnumber时,这意味着映射类型只能包含number类型的属性,并且因为number是原始的,它实质上意味着它与{{number相同1}}。这就是not assignable to number错误消息的原因 - typescript尝试查找大多数描述性类型以显示错误消息,而在您的情况下,它只是number