【问题标题】:Typescript oneOf Type for classesTypescript oneOf 类的类型
【发布时间】:2019-03-02 17:45:29
【问题描述】:
class CoreClass {
    coreProp: string
    // cannot do classABProp: string | number
    // as it interferes with persistence and cannot be easily 
    // used to define database schema. 
}

class ClassA extends CoreClass {
    classAProp: string

};

class ClassB extends CoreClass {
    classBPorp: number
};

class SubClass extends CoreClass {
    // Expected Props    
    // coreProp: string
    // classAProp: string || classBPorp: number
    // should have atleast one of the two.

}

所以我一直在寻找一种巧妙的方法来做到这一点。 我不愿意定义 SubClass 两次,这本质上是在做同样的事情。

我确实为每个类都有一个构造函数,所以我真的不想定义单独的类型来完成相同的任务。

似乎是一个微不足道的问题,但我无法理解它。

我们将不胜感激。

【问题讨论】:

  • 我不清楚Subclass 应该是什么......如果你想要一个代表任何子类的类型,你可以使用联合类型type Subclass = ClassA | ClassB
  • SubClass 会有自己的构造函数,因此将其分配为类型并不是最好的方法。
  • 所以 Subclass 需要同时继承 ClassAClassB 吗?或者您只是想确保它实现与ClassAClass B 相同的接口
  • SubClass 应该具有CoreClass 的所有属性,并且应该具有classAPropclassBProp,但应该至少具有这两个属性之一。这就是我所说的 oneOf 类型,因为类型 on 可以很容易地使用联合运算符来完成,而不是如何对类进行同样的操作。

标签: typescript inheritance multiple-inheritance typescript-typings


【解决方案1】:

您似乎希望在这里定义接口而不是类。怎么样:

interface CommonInterface {
  coreProp: string
}

interface InterfaceA extends CommonInterface {
    classAProp: string
};

interface InterfaceB extends CommonInterface {
    classBProp: number
};

type CoreInterface = InterfaceA | InterfaceB;

const testStringProp: CoreInterface = { coreProp: 'test', classAProp: "testString" };
const testNumberProp: CoreInterface = { coreProp: 'test', classBProp: 43 };

const testError: CoreInterface = { coreProp: 'test' }; 
//error: needs either classAProp or classBProp

通过实例化新对象来实现接口:

class CommonClass {
    coreProp: string
    // ...
}

class ClassA extends CommonClass {
    classAProp: string;

    constructor(props: InterfaceA) {
        super();
        this.coreProp = props.coreProp;
        this.classAProp = props.classAProp;
    }
};

class ClassB extends CommonClass {
    classBProp: number;

    constructor(props: InterfaceB) {
        super();
        this.coreProp = props.coreProp;
        this.classBProp = props.classBProp;
    }
};

class ClassAorB extends CommonClass {
    classAProp: string;
    classBProp: number;

    constructor(props: CoreInterface) {
        super();
        this.coreProp = props.coreProp;
        const propsA = props as InterfaceA;
        const propsB = props as InterfaceB;
        if (propsA.classAProp) {
            this.classAProp = propsA.classAProp
        }
        if (propsB.classBProp) {
            this.classBProp = propsB.classBProp
        }
    }
};


const objOfClassA = new ClassA({ coreProp: 'test', classAProp: 'testString' });
const objOfClassB = new ClassB({ coreProp: 'test', classBProp: 43 });
const objA = new ClassAorB({ coreProp: 'test', classAProp: 'testing' });
const objB = new ClassAorB({ coreProp: 'test', classBProp: 43 });

const testError = new ClassB({coreProp: 'test'}); 
//error: needs classBProp
const testAntotherErr = new ClassAorB({coreProp: 'test'}) 
//error: needs either classAProp or classBProp

【讨论】:

  • 好吧,我确实提到了'我确实为每个类都有一个构造函数,所以我真的不想定义单独的类型来完成同样的事情。'。这些是虚拟类,实际类有 15 到 20 个道具,在需要使用类和继承的这种情况下,真的不可能使用类型。
  • 更新为包含类实例化的示例
  • 所以这种方法的问题是,如果我执行`objA.classBProp`,它不会给出错误。即使 objA 没有 classBProp。
猜你喜欢
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
  • 2019-09-17
  • 2021-07-19
  • 2018-07-20
相关资源
最近更新 更多