我可以根据它是否存在于后代中来指定递归 属性 规则吗?
Can I specify a recursive property rule based on whether or not it is present in a descendant?
我想指定一个名为 Item
的类型,它可以嵌套如下:
两者都
type Item {
...;
item: Item;
answer: {
...;
//(does not contain property "item")
}
}
或
type Item {
...;
//(does not contain property "item")
answer: {
...;
item: Item
}
}
即Item
类型可以有 item:Item
作为直系子代 属性,或者作为 属性 answer
下面的孙代,但不能同时有。
上下文:我正在尝试实施 item property of the QuestionnaireResponse resource from the FHIR specification
这应该可以解决问题:
type FirstOrSecondLayer<T, I, A extends string> = XOR<T & I, T & Record<A, I>>
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
type Item = Expand<FirstOrSecondLayer<{
a: string
b: string
answer: {
c: string
}
},{
item: Item
}, "answer">
>
这里发生了很多事情。为了演示目的,我添加了一些额外的属性 a
、b
和 c
。您传递类型 without item
作为 T
。 I
是独占对象类型。对于 A
,您传递嵌套 I
.
的 属性 的名称
我使用了 and XOR
from 中的 Expand
类型。
以下是一些测试用例:
const t1: Item = {
a: "",
b: "",
item: {} as Item,
answer: {
c: ""
}
} // works
const t2: Item = {
a: "",
b: "",
answer: {
c: "",
item: {} as Item,
}
} // works
const t3: Item = {
a: "",
b: "",
item: {} as Item,
answer: {
c: "",
item: {} as Item, // error
}
}
让我知道这是否适用于您的用例。
我想指定一个名为 Item
的类型,它可以嵌套如下:
两者都
type Item {
...;
item: Item;
answer: {
...;
//(does not contain property "item")
}
}
或
type Item {
...;
//(does not contain property "item")
answer: {
...;
item: Item
}
}
即Item
类型可以有 item:Item
作为直系子代 属性,或者作为 属性 answer
下面的孙代,但不能同时有。
上下文:我正在尝试实施 item property of the QuestionnaireResponse resource from the FHIR specification
这应该可以解决问题:
type FirstOrSecondLayer<T, I, A extends string> = XOR<T & I, T & Record<A, I>>
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
type Without<T, U> = { [P in Exclude<keyof T, keyof U>]?: never };
type XOR<T, U> = (T | U) extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
type Item = Expand<FirstOrSecondLayer<{
a: string
b: string
answer: {
c: string
}
},{
item: Item
}, "answer">
>
这里发生了很多事情。为了演示目的,我添加了一些额外的属性 a
、b
和 c
。您传递类型 without item
作为 T
。 I
是独占对象类型。对于 A
,您传递嵌套 I
.
我使用了 XOR
from Expand
类型。
以下是一些测试用例:
const t1: Item = {
a: "",
b: "",
item: {} as Item,
answer: {
c: ""
}
} // works
const t2: Item = {
a: "",
b: "",
answer: {
c: "",
item: {} as Item,
}
} // works
const t3: Item = {
a: "",
b: "",
item: {} as Item,
answer: {
c: "",
item: {} as Item, // error
}
}
让我知道这是否适用于您的用例。