如何声明包含已知未知键的递归对象的类型



我想声明这种递归对象的类型,其中name链接和是必填字段

{
1: {
name: 'Youtube',
link: '/inventory/youtube',
1: {
name: 'home',
link: '/inventory/youtube/home'
}
},
2: {
name: 'Network Infrastructure',
link: '/inventory/network-infrastructure',
}
} 

我试过这样做,但得到错误(类型'string'的属性'name'不能分配给'string'索引类型'propTypes'),

type propTypes = {
name: string;
link: string;
[key: string | number]: propTypes
}; 

如果未知键是任何可能的字符串,那么你想要的在TypeScript中是不可能实现的。

{[key: string]: PropTypes}这样的string索引签名意味着:如果存在一个键类型为string的属性,那么它一定有一个PropTypes类型的值。但这意味着linkname属性也需要类型为PropTypes,而不是像您想要的string。这就是错误的来源。

您可能想说"每个string除了"link""name"应该有一个类型为PropTypes的值"。但目前还没有办法表达出来。在microsoft/TypeScript#17867中有一个长期存在的开放问题,要求这样的"hybrid"或";rest"指数签名。谁知道这样的事情何时或是否会实现。目前,TypeScript中还没有特定的类型是这样工作的。

有各种各样的解决方法,但它们都有点复杂。参见如何将Typescript类型定义为字符串字典,但只有一个数字"id";属性,以获得对不同可能方法的概述。


然而,在您的情况下,似乎未知键是特定的数字字符串,如"1""2",而不是任意字符串。在这种情况下,您可以使用number索引签名:

type PropTypes = {
name: string;
link: string;
[key: number]: PropTypes // okay
};

这是没有问题的,因为"name""link"不是数字字符串。说namelink属性应该是string值,而所有类似数字的属性都应该是PropTypes值,这不再是矛盾的。因此,您的递归对象满足以下定义:

const prop: { [key: number]: PropTypes } = {
1: {
name: 'Youtube',
link: '/inventory/youtube',
1: {
name: 'home',
link: '/inventory/youtube/home'
},
2: {
name: 'explore',
link: '/inventory/youtube/explore',
1: {
name: 'Indias Factory Customisation',
link: '/inventory/youtube/Indias-first-Factory-Customisation'
},
2: {
name: 'YouTube Mix',
link: '/inventory/youtube/YouTube-Mix'
}
}
},
2: {
name: 'Network Infrastructure',
link: '/inventory/network-infrastructure',
}
};

注意prop不是PropTypes类型,因为它缺少namelink属性。但是由于每个属性和嵌套的子属性都有这些属性,所以可以说prop的类型是{[key: number]: PropTypes}

Playground链接到代码

相关内容

  • 没有找到相关文章

最新更新