打字稿:类扩展了泛型类型 [英] Typescript: Class extends a Generic Type

查看:29
本文介绍了打字稿:类扩展了泛型类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这太通用了,但我希望创建一个类,该类将包含这样的通用类型的所有道具和原型:

I know it's too generic, but I wish to make a class that would have all props and prototype from a generic type like this:

class GenericExtend<T> extends T {
    constructor(data: T) {
        // here is a workaround to make these 2 classes unique
        const proto = { ...GenericExtend.prototype };
        Object.assign(proto, Object.getPrototypeOf(data));
        Object.setPrototypeOf(this, proto);
        Object.assign(this, data);
    }

    GenericMethod() { }
}

现在,我可以实例化 GenericExtend 类,然后像这样获取两个类的类型:

And now on, I could instanciate GenericExtend class and then get the types of the two classes like this:

const obj = new GenericExtend<Model>(data);
obj.GenericMethod(); // ok
obj.ModelMethod(); // good!

我的解决方案之一是使用交集,如下所示:

One of my solution is to use intersection, something like this:

const obj: GenericExtend & Model = new GenericExtend(data) as any;

它奏效了,但我不太喜欢.有什么我可以做的更好的事情吗?

It worked, but I didn't like that much. Is there something better that I can do?

推荐答案

TypeScript 不会让你实现或扩展另一个类型 T 除非 T 的所有键都是静态的在编译时已知.这可以防止 class GenericExtend实现 T {...} 成为你可以编写的东西.

TypeScript will not let you implement or extend another type T unless all the keys of T are statically known at compile time. That prevents class GenericExtend<T> implements T {...} from being something you can write.

相反,您必须使用交集来获得此行为...但是如果需要,您可以将类型断言限制在构造函数中,以便后续使用不需要它.让我们将 GenericExtend 重命名为:

Instead, you have to use an intersection to get this behavior... but you can confine the type assertion to the constructor function, if you want, so that subsequent uses will not require it. Let's rename GenericExtend out of the way:

class _GenericExtend<T> {
  constructor(data: T) {
    const proto = { ..._GenericExtend.prototype };
    Object.assign(proto, Object.getPrototypeOf(data));
    Object.setPrototypeOf(this, proto);
    Object.assign(this, data);
  }
  GenericMethod() { }
}

然后将 GenericExtend 重新定义为具有您想要的交集行为的类型和构造函数:

And then redefine GenericExtend as both a type and a constructor with the intersection behavior you want:

type GenericExtend<T> = _GenericExtend<T> & T;
const GenericExtend: new <T>(data: T) => GenericExtend<T> = _GenericExtend as any;

最后一个 as any 是我们需要的类型断言.现在你应该能够得到你想要的行为:

That last as any is the type assertion we need. Now you should be able to get the behavior you want:

interface Model {
  ModelMethod(): void;
}
declare const data: Model;

const obj = new GenericExtend(data);
obj.GenericMethod(); // ok
obj.ModelMethod(); // ok

游乐场连结代码

这篇关于打字稿:类扩展了泛型类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆