鉴于
// GIVEN
type Animal<T extends string> = {
id: T,
}
type Dog = Animal<"animal.dog"> & {
foo: string
}
type Cat = Animal<"animal.cat"> & {
bar: string
}
type MyType<T extends Dog | Cat = Dog | Cat> = { [K in T["id"]]: keyof T };
type MyTypeVariant<C extends "animal.dog" | "animal.cat" = "animal.dog" | "animal.cat"> = { [K in C]: keyof Animal<C> };
// EXPECT TO BE OK
const obj: MyType = {
"animal.dog": "foo",
"animal.cat": "bar"
}
// EXPECT TO FAIL
const fail: MyType = {
"animal.dog": "bar",
"animal.cat": "foo"
}
如果
value
(例如:“foo”)不是类型(例如:Cat)的键,可以从key
(例如:“ obj 的 Animal.cat")?
现在我收到错误
类型“foo”不能分配给类型“id”
因为“id”是
Dog
和 Cat
之间唯一的共同属性。
我想我需要在这里进行类型推断。
有什么想法吗?
您要找的类型是
type Type =
{ [T in Dog | Cat as T["id"]]: keyof T }
评估为
type Type = {
"animal.dog": "id" | "foo";
"animal.cat": "id" | "bar";
}
Dog | Cat
,对于该联合的每个成员T
,我们使用T["id"]
作为键,keyof T
作为值。由于我们迭代 T
的成员,因此键和值之间的相关性被保留。
如果我们需要按照您的方式进行操作,即在
K
而不是 T["id"]
上迭代 T
,我们需要检查 K
和 Extract
T
的正确成员,也许像这样:
type TypeGen<T extends Dog | Cat = Dog | Cat> =
{ [K in T["id"]]: keyof Extract<T, { id: K }> }
type Type = TypeGen
/* type Type = {
"animal.dog": "id" | "foo";
"animal.cat": "id" | "bar";
} */
但是按键重新映射更简单。