Как я могу напечатать метод с «this» внутри литерала объекта в машинописи? - PullRequest
2 голосов
/ 13 апреля 2020
const log = {
  counter: {
    a: 1,
    b: 2,
    c: 3,
  },
  increment(entry: keyof typeof this.counter){
    this.counter[entry]++;
  }
};

function incrementLog(entry:keyof typeof log.counter){
    log.counter[entry]++;
}

incrementLog('a'); // ok
incrementLog('d'); // error, must be 'a' | 'b' | 'c'
log.increment('a'); // ok
log.increment('d'); // no error

Playground Link

Я хочу, чтобы тип аргумента метода increment был равен keyof typeof log.counter, что равно 'a' | 'b' | 'c'. Я могу добиться этого в автономной функции, но она не работает в методе increment: 'this' is not defined.

Я также пробовал log.counter вместо this.counter в определении метода, но это создает «циклический инициализатор», который также не работает должным образом.

Я надеюсь не вводить log вручную или counter вручную, потому что когда я делаю изменения в объекте, я надеюсь внести изменения только в одном месте.

Ответы [ 3 ]

2 голосов
/ 13 апреля 2020

При написании объектно-ориентированного кода на TypeScript гораздо проще использовать синтаксис класса, чем заставить вещи работать с обычными литералами объекта:

class Log {
  counter = {
    a: 1,
    b: 2,
    c: 3
  };

  increment(entry: keyof Log['counter']) {
    this.counter[entry]++;
  }
}

const log = new Log();

function incrementLog(entry:keyof Log['counter']) {
  log.counter[entry]++;
}

incrementLog('a'); // ok
incrementLog('d'); // error
log.increment('a'); // ok
log.increment('d'); // error
2 голосов
/ 13 апреля 2020

Определить counter до log. Вы не можете ссылаться на тип в середине выражения, которое определяет тип. Вы можете легко избежать дублирования определения / инициализации.

const counter = {
    a: 1,
    b: 2,
    c: 3,
};
const log = {
  counter,
  increment(entry: keyof typeof counter){
    this.counter[entry]++;
  }
};

function incrementLog(entry:keyof typeof log.counter){
    log.counter[entry]++;
}

incrementLog('a'); // ok
incrementLog('d'); // error, must be 'a' | 'b' | 'c'
log.increment('a'); // ok
log.increment('d'); // error, must be 'a' | 'b' | 'c'
0 голосов
/ 13 апреля 2020

Вы должны создать тип или интерфейс для log:

interface Log<T extends {[key: string]: number}> {
    counter: T;
    increment(element: keyof T): void;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...