简体   繁体   English

扩展 Partial 接口的 Typescript 类

[英]Typescript class extending Partial interface

I would like to create a class that has all the properties of an interface, but does not actually declare those properties itself.The interface properties are appended during the build process and WILL exist at runtime.我想创建一个具有接口所有属性的类,但实际上并没有声明这些属性本身。接口属性是在构建过程中附加的,并且将在运行时存在。

I found this post that pointed me in the direction of using Partial<T> ...but that doesn't seem to work.我发现这篇文章指出了使用Partial<T>的方向……但这似乎不起作用。 The following code produces no compile errors.以下代码不会产生编译错误。

interface Animal {
    name: string;
}

interface HasConstructor {
    constructor: any;
}
//Do this to supress this error: "Type 'Dog' has no properties in common with type 'Partial<Animal>"
type OptionalAnimal = Partial<Animal> & HasConstructor;

class Dog implements OptionalAnimal {
    public constructor() {

    }
    public breed: string;
}

However, the name property is not available on the instance of Dog.但是, name属性在 Dog 实例上不可用。

var spot = new Dog();
spot.name = "Spot"; //ERROR: Property 'name' does not exist on type 'Dog'

I can get around this issue by creating another type and referencing it like this:我可以通过创建另一种类型并像这样引用它来解决这个问题:

type AnimalDog = Dog & Animal;

var spot: Animal = new Dog() as any;
spot.name = "Spot";

However, I can't construct a new instance of AnimalDog , and have to cast as any to get the types to line up, so I'm left using both AnimalDog and Dog in my code depending on the scenario.但是,我无法构建AnimalDog的新实例,并且必须AnimalDog转换为any才能使类型AnimalDog ,因此根据场景,我在代码中同时使用AnimalDogDog This also produces compile errors inside of Dog when referencing Animal types.当引用 Animal 类型时,这也会在 Dog 内部产生编译错误。

Is there a way to tell typescript that the class implements the interface, without explicitly declaring every interface property?有没有办法告诉打字稿该类实现了接口,而无需显式声明每个接口属性?

The problem is that Partial<T> will only allow you to implement the members will not require you to do so, and if you don't implement the member it will not be in the class.问题是Partial<T>只允许你实现成员不会要求你这样做,如果你不实现成员,它就不会在类中。

You can create a function that returns a class and this class will implement the interface.您可以创建一个返回一个类的函数,这个类将实现该接口。 The returned class will not actually have to declare any of the fields so they will all be undefined but this should be fine since the fields have to be optional anyway.返回的类实际上不必声明任何字段,因此它们都将是undefined但这应该没问题,因为无论如何这些字段都必须是可选的。

interface Animal {
    name: string;
}

type OptionalAnimal = Partial<Animal>;
function autoImplement<T>(): new () => T {
    return class { } as any;
}
class Dog extends autoImplement<OptionalAnimal>() {
    public constructor() {
        super();
    }
    public breed: string;
}

var spot = new Dog();

spot.name = "Spot"; // ok now

You can also cast the Dog class to specify that the returned instance has the members of Animal but these new members will not be accessible from inside the class:您还可以强制转换Dog类以指定返回的实例具有Animal的成员,但无法从类内部访问这些新成员:

interface Animal {
    name: string;
}

class _Dog {
    public constructor() {

    }
    public breed: string;
}

const Dog = _Dog as { new(): _Dog & Partial<Animal> } & typeof _Dog
type Dog = InstanceType<typeof Dog>

var spot = new Dog();

spot.name = "Spot"; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM