Проблема в том, что для class X {...}
тип X.prototype
представлен в TypeScript как X
, тип экземпляра класса.Из (устаревшего, но все еще значимого для этого вопроса) Спецификация языка TypeScript :
Тип функции конструктора, введенной объявлением класса, называется типом функции конструктора.Тип функции конструктора имеет следующие члены:
... [snip] ...
- Свойство с именем 'prototype', тип которого является экземпляром классатип с типом Любой, предоставленный в качестве аргумента типа для каждого параметра типа.
Таким образом, TypeScript считает, что тип Hello.prototype
равен Hello
.Это, конечно, не так в целом.Это верно для методов, но не для свойств экземпляра, как вы обнаружили.
Я искал проблемы в Github , но не нашел ничего, упоминающего об этом.Возможно, стоит открыть новый выпуск, предлагающий расширить тип прототипа класса, включив в него только методы.
РЕДАКТИРОВАТЬ: Эх, думаю, существует несколько существующих выпускает по этому поводу, которые по сути были отклоненными предложениями, потому что это повредило бы больше, чем помогло бы.
Я точно знаю, что это может испортить некоторые вещи (в настоящее время проверка x instanceof Class
будетсузить тип x
до Class['prototype']
, который, если его расширять, чтобы он включал только методы, повсеместно нарушал бы код каждого), поэтому я сомневаюсь, что они примут такое предложение. Но было бы неплохо, чтобы было официальное слово в этом вопросе.
В любом случае, резервное копирование вашей проблемы ... Код времени выполнения хорош, верно?И вы хотите, чтобы это работало:
new Hello().k("a");
и вы хотели бы, чтобы компилятор предупреждал о
new Hello().k("oopsie"); // error
?Если это так, то я бы предложил полностью исключить prototype
из уравнения и вместо этого использовать тип поиска вместо типа экземпляра Hello
:
class Hello {
abc = {
a: 'l',
b: 1,
}
k = (prop: keyof Hello['abc']) => {
console.log(prop)
}
}
Теперь это ведет себяпо желанию и не демонстрирует странности вокруг свойств экземпляров и прототипов классов в TypeScript.
Хорошо, надеюсь, это поможет.Удачи!