Свойство времени выполнения в Typescript - PullRequest
0 голосов
/ 09 июля 2020

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

export class Assessment {
    items: Question[];
    time?: number; // optional property
    scoreTotal?: number; // runtime computed property (sum of questions scores)
}

export class Question {
    score: number;
    statement: string;
    responses: string[];
    correctResponse: string;
}

scoreTotal? работает, но может вводить в заблуждение (можно подумать, что это необязательно).

Есть ли другой подход?

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

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Разделить Assessment на 2 типа; с scoreTotal и без него. Вы можете сделать это наиболее элегантно с типами «tagged union».

interface AssessmentBase {
    items: Question[];
    time?: number; // optional property
}

interface AssessmentWithoutScoreTotal extends AssessmentBase {
    type: "AssessmentWithoutScoreTotal",
}

interface AssessmentWithScoreTotal extends AssessmentBase {
    type: "AssessmentWithScoreTotal",
    scoreTotal: number; // runtime computed property (sum of questions scores)
}

type Assessment = AssessmentWithoutScoreTotal
    & AssessmentWithScoreTotal;

Конечно, Assessment больше не будет классом. Но вы можете сделать классом AssessmentWithoutScoreTotal или AssessmentWithScoreTotal, в зависимости от ваших потребностей. Но разве это должен быть класс? Я считаю, что простые интерфейсы работают намного лучше в большинстве ситуаций.

Тем не менее, вы должны быть осторожны, чтобы не изменить свойство items после вычисления totalScore, поэтому может иметь смысл ввести это а также:

interface Question {
    readonly score: number;
    statement: string;
    responses: string[];
    correctResponse: string;
}

interface AssessmentBase {
    time?: number; // optional property
}

interface AssessmentWithoutScoreTotal extends AssessmentBase {
    type: "AssessmentWithoutScoreTotal",
    items: Question[];
}

interface AssessmentWithScoreTotal extends AssessmentBase {
    type: "AssessmentWithScoreTotal",
    scoreTotal: number; // runtime computed property (sum of questions scores)
    readonly items: readonly Question[]; // Shouldn't mutate the scores anymore, since total has been precomputed.
}

type Assessment = AssessmentWithoutScoreTotal
    & AssessmentWithScoreTotal;
0 голосов
/ 09 июля 2020

Я могу думать о двух способах:

  1. Назначить его при создании класса. Я также сделал это readonly, но это не обязательно.
export class Assessment {
  items: Question[];
  time?: number;

  // You can assign it like this when the class is created
  readonly scoreTotal: number = this.computeTotalScoreSomehow();

  // You can also use the items and pass them to some external function
  readonly scoreTotal: number = computeTotalScoreSomehow(this.items);

  // Or do it in the constructor
  constructor(items: Question[]) {
    this.items = items;
    this.scoreTotal = /* Leave this up to you :) */
  }
}
Сделайте это по-настоящему вычисленным с помощью средства доступа get.
export class Assessment {
  items: Question[];
  time?: number;

  get scoreTotal(): number {
    return calculateScoreSomehow() // Up to you :)
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...