TypeScript: Extract then Omit from union



假设我有一个Vehicle并集类型是这样的:

interface Car {
color: string;
doors: number;
wheels: number;
}
interface Plane {
color: string;
wings: number;
}
type Vehicle = Car | Plane;

我希望(1)从这个联合中提取扩展给定类型参数的类型(这可以很容易地使用Extract实用程序类型实现),(2)从提取的类型中省略相同类型参数的键。下面是期望的输出:

type Result1 = ExtractOmit<{ wheels: number; }>;
// This should give me the result of Omit<Car, "wheels">:
// { color: string; doors: number; }
type Result2 = ExtractOmit<{ wings: number; }>;
// This should give me the result of Omit<Plane, "wings">:
// { color: string; }
type Result3 = ExtractOmit<{ foo: number; }>;
// This should produce an error since foo is neither in Car nor Plane

这是一个不成功的尝试:

type ExtractOmit<T> = Omit<Extract<Vehicle, T>, keyof T>;
// T extends what?

右边的部分对我来说似乎是正确的,但我不知道如何放置左边的部分。

任何建议吗?

打印稿操场

interface Car {
color: string;
doors: number;
wheels: number;
}
interface Plane {
color: string;
wings: number;
}
type Vehicle = Car | Plane;
type OmitExtract<T extends Partial<Vehicle>> = Omit<Extract<Vehicle, T>, keyof T>;
type Result = OmitExtract<{ wheels: number; }>;
type Result1 = OmitExtract<{ wheels: number; }>;
// This should give me the result of Omit<Car, "wheels">:
// { color: string; doors: number; }
type Result2 = OmitExtract<{ wings: number; }>;
// This should give me the result of Omit<Plane, "wings">:
// { color: string; }

上述操作似乎如预期的那样运行。

这里的关键是使用"Vehicle"(我注意到您之前使用了Element),并让T扩展左侧的Partial,为Extract提供必需的超类型,以便知道正确地从中提取什么。

编辑:playground链接

最新更新