多个嵌套泛型的函数组合的Typescript等价物

多个嵌套泛型的函数组合的Typescript等价物,typescript,generics,Typescript,Generics,有时,为了创建一个新类型,我会对一个类型执行很多操作,例如: type Complex=省略 是否存在功能性组合或管道功能的等价物,以便创建此类类型更具可读性,即: type Complex=管道 不,该语言没有实现此功能所需的高阶类型操作。我能想象的最接近的方法是从类型级别降低到值级别,滥用最近的,然后再向上移动到类型级别。这并不漂亮,你最终会得到一些无用的运行时代码来引导 这就是我的意思。我假设你有这些定义: interface Interface1 { a: string;

有时,为了创建一个新类型,我会对一个类型执行很多操作,例如:

type Complex=省略
是否存在功能性
组合
管道
功能的等价物,以便创建此类类型更具可读性,即:

type Complex=管道

不,该语言没有实现此功能所需的高阶类型操作。我能想象的最接近的方法是从类型级别降低到值级别,滥用最近的,然后再向上移动到类型级别。这并不漂亮,你最终会得到一些无用的运行时代码来引导

这就是我的意思。我假设你有这些定义:

interface Interface1 {
    a: string;
    "omitted field": boolean;
}
type Merge<T, U> = T & U;
type ManualComplex = Omit<Merge<Interface1, { modifiedField: false }>, 'omitted field'>
/* type ManualComplex = {
    a: string;
    modifiedField: false;
} */
最后,我编写了一些实际的运行时代码,这些代码愚弄了编译器,使其对您想要的类型进行计算,尽管在运行时代码会短路到
true
(这很好,因为如果它实际调用不存在的
pipe()
函数,您会得到一些令人讨厌的运行时错误):


是的,它的类型与
ManualComplex
相同。不可能部分应用类型构造函数,因此在当前级别的TS中不可能使用IMOP。您只能传递经过计算的类型,例如,在您的示例中,您将右参数应用于
ommit
,将右参数应用于
Merge
。只能将具体类型传递到泛型参数中,不能传递类型构造函数。对于类型上的某些特定操作,您可以考虑更多的变通方法。
declare const CurriedOmit: <K extends PropertyKey>() => <T>(t: T) => Omit<T, K>;
declare const CurriedMerge: <U>() => <T>(t: T) => Merge<T, U>;
declare const Id: <T>() => T
// there may be some variadic pipe but for now let's do this:
declare const pipe: {
    <A>(a: A): A;
    <A, B>(a: A, b: (a: A) => B): B;
    <A, B, C>(a: A, b: (a: A) => B, c: (b: B) => C): C;
    <A, B, C, D>(a: A, b: (a: A) => B, c: (b: B) => C, d: (c: C) => D): D;
}
const complex = (true as false) || pipe(
    Id<Interface1>(),
    CurriedMerge<{ modifiedField: false }>(),
    CurriedOmit<'omitted field'>()
);
type Complex = typeof complex;
/* type Complex = {
    a: string;
    modifiedField: false;
} */