gpt4 book ai didi

typescript - 类型注释 : How to inherit from a Mixin of several classes and preserve static methods?

转载 作者:搜寻专家 更新时间:2023-10-30 21:34:52 24 4
gpt4 key购买 nike

It is only the ts annotation problem, in js runtime works everything as expected.

对于多重继承/混合,我们有一个运行时方法,它接受类/对象并创建复合(混合)类。

class A {
a: string
static staticA: string
}
class B {
b: string
static staticB: string
}
class C extends mixin(A, B) {
c: string
static staticC: string
}

所以我们的 mixin方法创建了 C 的混合类继承。现在我们有一些注释问题。简单 mixin声明看起来像这样(实际上,mixin 也接受 T1T2 的对象,但为了简单起见,我从代码中删除了它):

interface Constructor<T = {}> {
new (...args: any[]): T;
}

declare function mixin<T1 extends Constructor, T2 extends Constructor> (
mix1: T1,
mix2: T2
): new (...args) => (InstanceType<T1> & InstanceType<T2>)

不幸的是,mixin 返回的类型松散 T1 的静态方法和 T2 .

C. /* only 'staticC' is present in autocomplete */
let c = new C;
c. /* all - 'a', 'b' and 'c' are present in autocomplete */

我还尝试返回类型 T1 & T2 , 但在 mixin(A, B) 中得到错误

[ts] Base constructors must all have the same return type.

有什么解决办法吗?


最终解决方案

感谢@titian-cernicova-dragomir。我在这里添加我的最终解决方案,我扩展了注释以支持对象,而不仅仅是类,希望它对某些人有所帮助。

// Extract static methods from a function (constructor)
type Statics<T> = {
[P in keyof T]: T[P];
}

declare function mixin<
T1 extends Constructor | object,
T2 extends Constructor | object,
T3 extends Constructor | object = {},
T4 extends Constructor | object = {},
> (
mix1: T1,
mix2: T2,
mix3?: T3,
mix4?: T4,
):
(T1 extends Constructor ? Statics<T1> : {}) &
(T2 extends Constructor ? Statics<T2> : {}) &
(T3 extends Constructor ? Statics<T3> : {}) &
(T4 extends Constructor ? Statics<T4> : {}) &
(new (...args: T1 extends Constructor ? ConstructorParameters<T1> : never[]) =>
(T1 extends Constructor ? InstanceType<T1> : T1) &
(T2 extends Constructor ? InstanceType<T2> : T2) &
(T3 extends Constructor ? InstanceType<T3> : T3) &
(T4 extends Constructor ? InstanceType<T4> : T4)
);



class A {
a: string
static staticA: string
}
class B {
b: string
static staticB: string
}
const Utils = {
log () {}
}
class C extends mixin(A, B, Utils) {
c: string
static staticC: string
}
C. // has 'staticA', 'staticB', 'staticC'
let c = new C;
c. // has 'a', 'b', 'c', 'log'

我还添加了第一个类的构造函数(如果有)的参数支持。

...args: T1 extends Constructor ? ConstructorParameters<T1> : never[] .

不幸的是,我找不到制作 mixin 的解决方案注释以支持任意数量的参数,目前我做了 4 个,因为这对我的情况来说已经足够了。虽然我们的 js mixin可以接受任意数量的类/对象来创建混合类。

最佳答案

你可以保持原创mixin按原样运行,并与返回的构造函数相交 T1T2

class A {
a!: string
static staticA: string
}
class B {
b!: string
static staticB: string
}
class C extends mixin(A, B) {
c!: string
static staticC: string
}

interface Constructor<T = {}> {
new(...args: any[]): T;
}

declare function mixin<T1 extends Constructor, T2 extends Constructor>(
mix1: T1,
mix2: T2
): {
new(...args: any[]): (InstanceType<T1> & InstanceType<T2>)
} & T1 & T2

C.staticA
C.staticB
C.staticC
let c = new C;
c.a
c.b
c.c

Playground link

你提到你试过 T1 & T2该方法的问题在于不会更改构造函数以返回 (InstanceType<T1> & InstanceType<T2>) .您必须将这个新签名添加到构造函数和原始类中。

关于typescript - 类型注释 : How to inherit from a Mixin of several classes and preserve static methods?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53191711/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com