Ответ прост: если машинопись может доказать, что доступ безопасен, индексация разрешена.
Когда вы пишете this['bar']
машинописный текст видит строковый литерал, и он может легко проверить, что this
имеет свойство bar
Когда вы пишете const index = 'bar';
, вы можете подумать, что тип index
равно string
, но на самом деле это не так, тип index
является строковым литеральным типом 'bar'
, поэтому для машинописного текста будет известно единственно возможное значение в index
: 'bar'
, Поскольку index
может удерживать только строку, машинопись может проверить, что доступ this[index]
действителен, проверив, что this
имеет свойство bar
Когда вы пишете const props:string[]
машинопись не сделает никаких других выводов около props
это массив string
. Это означает, что при доступе к this[prop]
машинопись должна быть уверена, что this
индексируется любым string
, что, поскольку у него нет сигнатуры индекса, это не так, и, следовательно, при доступе возникает ошибка. Если вы используете as const
, чтобы сделать вывод логических типов ts для массива вместо string
и удалить явную аннотацию, вы сможете выполнить индексный доступ:
const props = ['bar'] as const
for(const [key,value] of props.entries()) {
console.log(value);
console.log(this[value])//ok
}
for(let i=0;i<props.length;i++) {
console.log(this[props[i]])
}
Playground Link
Вы также можете использовать утверждение типа, если уверены, что prop
является ключом this
:
const props = ['bar']
for(const [key,value] of props.entries()) {
console.log(this[value as keyof this])
}
Или, если вы хотите по-настоящему вычурно, вы можете используйте защиту от пользовательских типов или утверждение пользовательских типов, но здесь это кажется излишним.