我试图声明一个具有以下结构的
const
:
type Element = null | {parent: keyof typeof TREE};
const TREE = {
'a': null,
'b': {parent: 'a'},
} satisfies Record<string, Element>;
由于循环引用,这给我带来了麻烦。如何绕过它并获得相同的功能,以便 TS 将来允许我向
TREE
添加节点并仍然检查树中是否存在每个 parent
?
您可以将其分成两个单独的部分,而不是尝试一次声明并检查
TREE
本身。首先,你声明一些事情:
type Element = null | { parent: keyof typeof TREE };
const TREE = {
'a': null,
'b': { parent: 'a' },
} as const;
然后然后你检查它们:
const check: Record<string, Element> = TREE; // okay
这打破了循环性,因为
TREE
的类型除了初始化器之外不依赖于任何东西。据推测,您正在使用 satisfies
运算符 为 TREE
初始值设定项提供上下文,以便它能够跟踪 parent
属性的文字类型,而不是推断
string
。您可以使用 const
断言来代替这样做,它也可以保留文字类型而不是循环。
然后,当且仅当该分配是可接受的时,检查 const check: Record<string, Element> = TREE
才会编译。如果
TREE
具有任何类型不是
Element
的属性,那么您将收到错误:
const TREE = {
'a': null,
'b': { parent: 'c' }, // <-- 'c'
} as const;
const check: Record<string, Element> = TREE; // error!
// ~~~~~
// Type '"c"' is not assignable to type '"a" | "b"'.
该错误可能并不完全是您想要的位置,但它至少告诉您问题是什么。