Принудительное использование только для чтения в интерфейсах и / или классах

#angular #typescript #class #interface #readonly

#angular #typescript #класс #интерфейс #только для чтения

Вопрос:

Я работаю над классом, который я использую в качестве модели, и я хочу убедиться, что данные доступны только для чтения. Это достаточно просто само по себе, но, похоже, становится сложнее, когда данные вложены. Позвольте мне привести пример моего кода, чтобы сделать это более понятным:

 export class MyModel {
  readonly One: IOne;
  readonly Two: ITwo;
  readonly Three: IThree;

  constructor() {
    this.One.A = "foo";
    this.One.B = "bar";
    this.Two.C = "totally";
    this.Two.D = "utterly";
    this.Three.E = "completely";
    this.Three.F = "messed up"
  }
}

interface IOne {
  A: string;
  B: string;
}

interface ITwo {
  C: string;
  D: string;
}

interface IThree {
  E: string;
  F: string;
}
  

Затем в компоненте:

 import { MyModel } from './my.model';

export MyComponent {
  
  dataB:string;
  dataD:string;
  dataE:string;

  constructor(
    private mymodel: MyModel
  ){
    this.dataB = mymodel.One.B; // works as expected
    mymodel.Two = ""; // gives error since it is readonly, as expected
    mymodel.Three.F = "something else"; // works, but I want this to be readonly as well
  }

}
  

Идея в том, что я могу хранить свои данные в местах, где они имеют наибольший смысл, но также позволяют моей IDE давать подсказки о том, что доступно при вводе mymodel.One.B . Но мне нужно, чтобы свойства (не уверен, что я использую правильный термин здесь) из интерфейсов также были доступны только для чтения.

Если я добавлю только для чтения в интерфейсы, я, конечно, получу ошибку в MyModel, потому что я не могу установить значения чего-то, что доступно только для чтения. Чтобы обойти это, я попытался создать другие классы, которые реализуют эти интерфейсы, установить доступ только для чтения в классах, затем использовать классы вместо интерфейсов, это не выдает ошибку, но им все еще не запрещено присваивать значения в MyComponent. Пример:

 export class MyModel {
  readonly One: One;
  readonly Two: Two;
  readonly Three: Three;

  constructor() {}
}

class One implements IOne {
  readonly A = "foo";
  readonly B = "bar";
}

class Two implements ITwo {
  readonly C = "totally";
  readonly D = "utterly";
}

class Three implements IThree {
  readonly E = "completely";
  readonly F = "messed up";
}

interface IOne {
  A: string;
  B: string;
}

interface ITwo {
  C: string;
  D: string;
}

interface IThree {
  E: string;
  F: string;
}
  

Результат в MyComponent тот же. Как мне обеспечить доступ только для чтения для A, B, C и т.д.?

Комментарии:

1. Я думаю, взгляните на readonly тип утилиты, который может вам помочь: typescriptlang.org/docs/handbook /…

Ответ №1:

Я нашел правильный способ заставить это работать.

Я этого не осознавал, но способ, которым я написал MyModel, выдает ошибку в тот момент, когда MyComponent создает ее экземпляр, потому что mymodel.Значение A не определено. Хитрость заключалась в том, чтобы установить значения вне конструктора, что также привело меня к решению моего первоначального вопроса:

 export class MyModel {
  readonly One: IOne = {
    A: "foo",
    B: "bar"
  }

  constructor(){}
}

interface IOne {
  readonly A: string,
  readonly B: string
}
  

Это привело к правильной ошибке при попытке присвоить значение mymodel.One.A в MyComponent.