【问题标题】:TypeScript: how to define a type that returns a intersection of an arbitrary number of other typesTypeScript:如何定义返回任意数量其他类型的交集的类型
【发布时间】:2022-01-26 01:48:09
【问题描述】:

我正在尝试编写一个返回任意数量其他类型的交集的类型。类似的东西

type TypeofStatementIntersections<CL extends Function[]> = { [SN in keyof CL]: (builder: CL[SN]) => CL[SN] }[number] extends
    (arg1: infer IT) => void ? IT : never;

function MixStaticReferencesOf<T1 extends Function[]>(...builder: T1): TypeofStatementIntersections<T1> {

    return Object.assign({});
}

class C1 {

    p1 = 1;

    static staticProp1: string = `class property defined in ${this.name}`;
    
    static staticMethod1() {

    }

}

class C2 {

    static staticProp2: string = `class property defined in ${this.name}`;

    static staticMethod2() {
        return C2.staticProp2;
    }

    method2() {
        return C2.staticProp2;
    }

}

class C3 {

    static staticProp3: string = `class property defined in ${this.name}`;

    static staticMethod3() {

    }

}

const MixedStaticReferences = MixStaticReferencesOf(C1, C2, C3); // : typeof C1 & typeof C2 & typeof C3

它可以混合静态引用,但我想要另一种类型来引用实例混合。我想定义一个返回C1 &amp; C2 &amp; C3 &amp; ...的类型,例子定义了同伴返回类型typeof C1 &amp; typeof C2 &amp; ...

有可能吗?

【问题讨论】:

  • 为什么typeof C1 &amp; typeof C2 不正确?您想混合静态。typeof T 表示类的静态侧TT 是实例类型。
  • @TitianCernicova-Dragomir 抱歉,我更新了帖子。我想要另一种类型来引用实例混合而不是静态引用。

标签: typescript


【解决方案1】:

我们这里需要几块。

首先你需要一个构造函数的类型,它可以接受任何可以用new调用的函数:

type Constructor = new (...args: any[]) => any

然后您需要能够将并集合并为交集。我喜欢这个来自this answer

type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

我们需要的最后一块是the InstanceType utility type

const c1: InstanceType<typeof C1> = new C1() // same as type `C1`

把它们放在一起你可以很简单地输入你的函数:

const MixedInstanceReferences =
  <T extends Constructor[]>(...args: T):
    UnionToIntersection<InstanceType<T[number]>> => {
  return {} as any // TODO: implementation
}

它接受一个构造函数列表,将它们转换为T[number] 的联合,使用InstanceType 获取该联合的任何成员的实例类型,然后将该联合合并为与UnionToIntersection 的交集

你想要什么:

const allCs = MixedInstanceReferences(C1, C2, C3) // C1 & C2 & C3
allCs.p1
allCs.method2

Playground

【讨论】:

  • 非常感谢。但是,如果我想像那样使用const allCs: UnionToIntersection&lt;C1, C2, C3&gt; = new AnAnyConstructor(C1, C2, C3);UnionToIntersection 类型应该怎么看?
  • 不清楚你的问题是什么。你能详细说明一下吗?
【解决方案2】:

我发现了如何做到这一点。 借鉴同事韦恩的回应...... 我需要改变这种平静

... ((k: infer I) => void) ? I : never

... ((k: infer I) => void) ? new () => I : never

现在,函数可以构造了。

const ConstructibleFunction = MixedInstanceReferences(C1, C2, C3)
const instance = new ConstructibleFunction
instance.p1; // ok

我通过查看从 Function 类继承的静态属性 bind 的效果得到了这一点。

谢谢。

【讨论】:

    猜你喜欢
    • 2021-04-23
    • 1970-01-01
    • 2022-10-12
    • 2020-04-09
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 2017-08-23
    • 2021-07-27
    相关资源
    最近更新 更多