我在下面的例子中有键值对对象
preg_split('/(<|>)/m', $xmlString);
但它会引发错误,例如
interface ItemType {
a: number;
b: string;
}
const list = {
first: {a: 1, b: 'one'},
second: {a: 2, b: 'two'},
third: {a: 3, b: 'three'},
} as { [key in keyof typeof list]: ItemType }
。
我希望所有项目都属于 TS2313: Type parameter 'key' has a circular constraint.
类型,但仍希望列表保存我插入的键。如果我将它转换为 ItemType
,我将丢失列表的键名。 :(
答案 0 :(得分:7)
如果您想验证一个值是否可分配给某个类型,而不将其扩展到该类型,并且可能会丢弃您关心的信息,则可以使用辅助标识函数,如下所示:
const itemDict = <K extends PropertyKey>(dict: { [P in K]: ItemType }) => dict;
此处 itemDict()
应该只接受您正在寻找的类型的对象作为参数:其键是任何类似键的 K extends PropertyKey
,编译器会在您调用它时推断出它,并且其属性为 ItemType
。因为键集 K
是类型的一部分,所以不会被遗忘:
const list = itemDict({
first: { a: 1, b: 'one' },
second: { a: 2, b: 'two' },
third: { a: 3, b: 'three' },
});
list.second.a.toFixed(); // okay
list.fourth; // error!
// Property 'fourth' does not exist on type
// '{ first: ItemType; second: ItemType; third: ItemType; }'
请注意,编译器将 list
推断为类型 {first: ItemType, second: ItemType, third: ItemType}
,根据需要。