#typescript #inheritance #static-typing
#typescript #наследование #статическая типизация
Вопрос:
У меня есть интерфейс с более чем 200 свойствами и класс, который использует эти же свойства.
interface MyProperties {
property1: string
property2: string
...
property232: string
}
class MyClass {
constructor() {
this.property1 = 'foo';
this.property2 = 'bar';
...
this.property232 = 'bar';
}
}
Прямо сейчас typescript выдаст мне эту ошибку: Property 'property1' does not exist on type 'MyClass'.
Есть ли способ сообщить typescript, что свойства моего класса поступают из MyProperties
интерфейса?
Я не хочу делать что-то подобное:
class MyClass {
property1: string
property2: string
constructor() {
this.property1 = 'foo';
this.property2 = 'bar';
}
}
поскольку интерфейс уже широко используется в моем коде, и я не хочу повторять эти типизации.
Ближе всего я подошел к этому
class MyClass {
property1: MyProperties['property1'];
property2: MyProperties['property2'];
...
property232: MyProperties['property232'];
constructor() {
this.property1 = 'foo';
this.property2 = 'bar';
...
this.property232 = 'bar';
}
}
но это не очень красиво, поскольку в моем реальном коде у меня более 200 свойств
Комментарии:
1. Два предоставленных ответа решают вашу проблему, за исключением того, что вы говорите, что они не работают для вас, потому что у вас более 200 свойств. Затем вам нужно сделать «200 свойств» в центре вашего вопроса, а не в виде крошечного комментария в конце. Я переместу его наверх, но вам нужно добавить больше информации.
2. Например, вам нужно предоставить больше информации об этих более чем 200 свойствах: все ли они находятся в одном интерфейсе? При таком количестве свойств имеет ли смысл статическая проверка типов? Вы должны предоставить значения для всех из них (если они не являются необязательными), чтобы у вас все еще была «не очень красивая» проблема. Если вы предоставите подробную информацию о своих потребностях, а не «заставите этот код работать», мы можем предложить лучшие решения.
3. Нет, это не то, как интерфейсы работают в Typescript или ЛЮБОМ другом языке, который я знаю. Вы не наследуете интерфейсы, вы их реализуете , а «реализовать» означает, что вам нужно делать то, что вы не хотите делать. Вы можете превратить свой интерфейс в абстрактный класс, а затем использовать наследование… И, ПОЖАЛУЙСТА, ответьте на другие мои вопросы, либо здесь, в комментариях, либо обновив свой вопрос (лучше).
4. @Inigo Они все в одном интерфейсе и представляют собой смесь всевозможных типов. Для любого другого типа данных я могу просто сделать
const myObject: MyType = {}
. Из ответов здесь я предполагаю, что для классов нет эквивалента.5. Что такое
MyType
? Вы не можете этого сделатьconst myObject: MyProperties = {}
. Вы не можете соответствовать типу, фактически не реализуя все необязательные поля этого типа, если вы не используете наследование. Не стесняйтесь поправлять меня примером в Typescrtipt Playground, например, вот так , и, пожалуйста, укажите в своем вопросе. Вам нужно больше работать с ясностью, а не нам. Моя интуиция говорит, что вы в замешательстве. Спасибо.
Ответ №1:
Ну, просто добавьте implements MyProperties
предложение в класс:
interface MyProperties {
property1: string
property2: string
}
class MyClass implements MyProperties {
property1: string;
property2: string;
constructor() {
this.property1 = 'foo';
this.property2 = 'bar';
}
}
Комментарии:
1. Тогда мне все равно нужно вручную добавить все мои типы в класс. У меня есть интерфейс с более чем 200 методами, поэтому я бы предпочел не вводить все это дважды
2. Если это методы, вам, конечно, нужно будет реализовать их самостоятельно в любом случае? Может быть, вам нужен абстрактный класс?
3. Я согласен, что вам, вероятно, нужен абстрактный класс, а не интерфейс
4. Тип с более чем 200 свойствами пахнет для меня очень подозрительно. Бьюсь об заклад, что если бы мы знали о лежащей в основе проблеме, мы бы порекомендовали что-то совершенно другое.
Ответ №2:
Прямо сейчас typescript выдаст мне эту ошибку
Это потому, что в классе нет определения для этих свойств. Вы должны сообщить компилятору TypeScript, который MyClass
обладает этими свойствами:
class MyClass {
property1: string;
property2: string;
constructor() {
this.property1 = 'foo';
this.property2 = 'bar';
}
}
Теперь компилятор знает, какие свойства MyClass
имеет, и может реализовать этот MyClass
реализующий MyProperties
интерфейс:
interface MyProperties {
property1: string
property2: string
}
class MyClass {
property1: string;
property2: string;
constructor() {
this.property1 = 'foo';
this.property2 = 'bar';
}
}
const a: MyProperties = new MyClass(); // no error here
Также вы можете явно реализовать MyProperties
интерфейс для улучшения читаемости кода с помощью implements MyProperties
:
interface MyProperties {
property1: string
property2: string
}
class MyClass implements MyProperties {
property1: string;
property2: string;
constructor() {
this.property1 = 'foo';
this.property2 = 'bar';
}
}
const a: MyProperties = new MyClass(); // no error here too
Комментарии:
1. но в этом случае мне все равно придется вводить каждое свойство дважды, что не идеально для поддержания. У меня в моем классе более 200 свойств.