我正在尝试创建一个泛型类型,它从类型中获取属性名称和属性类型,并使用它们来创建区别性的联合类型。例如:
type FooBar = {
foo: string;
bar: number;
};
将映射到:
type FooBarPair = {
key: "foo",
value: string
} | {
key: "bar",
value: number
}
我最初的尝试是:
type Pairs<T> = {
[TKey in keyof T]: {
key: TKey;
value: T[TKey];
};
};
type Pair<T> = Pairs<T>[keyof T];
但是当我尝试将其应用于上述类型时:
let pair: Pair<FooBar> = {
key: "foo",
value: 3
};
我希望编译错误,但是没有。当我检查Pair<FooBar>
的类型时,我发现它等同于:
{
key: "foo" | "bar";
value: string | number;
}
我认为这可能是打字稿中的一个错误,但我想知道是否还有其他方法可以实现这一目标。
答案 0 :(得分:3)
是的,有办法实现这一目标。事实证明,Typescript推断出所需的类型
`{ key: "foo"; value: string; } | { key: "bar"; value: number; }`
删除中间通用类型type Pair<T> = Pairs<T>[keyof T];
并在每次使用时将其展开为Pairs<FooBar>[keyof FooBar]
内联:
type Pairs<T> = {
[TKey in keyof T]: {
key: TKey;
value: T[TKey];
};
};
type FooBar = {
foo: string;
bar: number;
};
let pair: Pairs<FooBar>[keyof FooBar] = {
key: "foo",
value: 3
};
完整的错误消息是
Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'.
Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; }'.
Types of property 'value' are incompatible.
Type 'number' is not assignable to type 'string'.
我不确定在任何一种情况下推断的“正确”类型是什么,但像Pair<T> = Pairs<T>[keyof T]
这样的速记类型的引入不应该影响类型推断IMO。看起来像一个错误。