#typescript #inheritance #multiple-inheritance #typescript-typings
#typescript #наследование #множественное наследование #typescript-типизации
Вопрос:
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.
}
Итак, я искал аккуратный способ сделать это.
Я не отказываюсь определять подкласс дважды, что, по сути, делает одно и то же.
У меня есть конструктор для каждого класса, поэтому я действительно не собираюсь определять отдельные типы для достижения того же самого.
Кажется тривиальной проблемой, но я не могу разобраться в ней.
Любая помощь по тому же вопросу была бы высоко оценена.
Комментарии:
1. Мне не ясно, что
Subclass
должно быть… Если вам нужен тип, представляющий какой-либо подкласс, вы могли бы использовать тип объединенияtype Subclass = ClassA | ClassB
2. Ну, у подкласса будет свой собственный конструктор, поэтому присвоение ему типа — не лучший способ сделать это.
3. Итак,
Subclass
нужно наследовать от обоихClassA
иClassB
? Или вы просто хотите убедиться, что он реализует тот же интерфейс, что иClassA
иClass B
4.
SubClass
должен обладать всеми свойствамиCoreClass
и должен иметьclassAProp
илиclassBProp
, но должен иметь хотя бы один из двух реквизитов. Это то, что я имел в виду под oneOf type, поскольку типы on могли бы легко сделать это с помощью оператора объединения, но не очень, как сделать то же самое с классами.
Ответ №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
Комментарии:
1. Ну, я упоминал ‘У меня есть конструктор для каждого класса, поэтому я действительно не собираюсь определять отдельные типы для выполнения одного и того же.’. Это фиктивные классы, у реальных классов от 15 до 20 реквизитов, на самом деле невозможно использовать типы в таком сценарии, нужно использовать классы и наследование.
2. Обновлено, чтобы включить пример создания экземпляра класса
3. Итак, проблема с этим подходом заключается в том, что если я выполняю ` objA.classBProp`, это не выдает ошибку. Даже несмотря на то, что objA не имеет classBProp.