Это известная проблема , как вам известно из ваших комментариев на GitHub. Подводя итог здесь:
В настоящее время вывод типов не работает так, как вы этого хотите, так как компилятор рассматривает оригинал как эквивалент чего-то вроде этого:
const barDeco = decorate(v => v + 1); // error
barDeco(Foo.prototype, "bar");
const wrongBarDeco = decorate(v => v + '');
wrongBarDeco(Foo.prototype, "wrongBar");
И вызовы decorate()
в barDeco
и wrongBarDeco
не имеют достаточной информации о типе для компилятора, чтобы вывести общий тип, и поэтому он выводится как {}
, что приводит к большой печали. Декоратор - это, по сути, карри-функция f(x)(y)
, и для исправления этого компилятор должен будет выводить тип f
из типа y
, что является новым видом контекстной типизации. Может быть, декораторы могут быть специально созданы для такого вывода; скорее всего, это будет серьезное изменение для карри-функций.
На данный момент единственный способ справиться с этим - вручную указать универсальный параметр при вызове декоратора, как в
class Foo {
@decorate<number>(v => v + 1) bar: number = 1; // okay
@decorate<number>(v => v + '') wrongBar: number = 1; // error
}
или для аннотирования вашего обратного вызова вручную, как в
class Foo {
@decorate((v: number) => v + 1) bar: number = 1; // okay
@decorate((v: number) => v + '') wrongBar: number = 1; // error
}
Эти обходные пути не оптимальны, но они работают, поэтому у вас есть какой-то способ справиться с вещами, если только и до тех пор, пока не будет решено Microsoft / TypeScript # 2607 . Есть много, много открытых вопросов, поэтому я не ожидал бы увидеть много движения по этому вопросу. Вероятность возрастет, если все больше людей займутся этим вопросом и дадут ему ? и опишут убедительные варианты использования и веские причины, по которым обходные пути недостаточны. Поскольку вы уже сделали это, я думаю, что вам не нужно больше ничего делать, кроме как двигаться дальше. Если будущие читатели заботятся об этом, они могут проверить проблему в GitHub и внести свой вклад.
Извините, нет лучшего ответа для вас. Удачи!