Рассмотрим следующий фрагмент кода TypeScript, который компилируется и успешно работает:
class UserSettings {
[key: string]: boolean;
setting1: boolean = false;
setting2: boolean = false;
setting3: boolean = false;
otherOtherSetting: boolean = true;
}
const settings = new UserSettings();
const checkSettingChanged = (setting: string, value: boolean) => {
if (value !== settings[setting]) {
console.log(`The setting of ${setting} changed, updating it!`);
settings[setting] = value;
}
};
Однако этот код отстой, потому что, указав [key: string]: boolean
в классе, мы теряем класс безопасности. Другими словами, следующий код успешно скомпилируется, но выдаст ошибку времени выполнения:
function someOtherFunction() {
// Oops, I forgot to specify setting 4 in the class definition above,
// so this code should fail to compile, but TypeScript doesn't care,
// and now I will get a stupid runtime error
if (settings.setting4) {
console.log('Setting 4 is enabled!');
}
}
ОК. Так можно ли удалить [key: string]: boolean
в определении класса? Давайте попробуем и посмотрим, что произойдет:
class UserSettings {
// This is just a "normal" TypeScript class now
setting1: boolean = false;
setting2: boolean = false;
setting3: boolean = false;
otherOtherSetting: boolean = true;
}
const settings = new UserSettings();
const checkSettingChanged = (setting: string, value: boolean) => {
// Hopefully, adding this runtime check should satisfy the TypeScript compiler
if (!(setting in settings)) {
throw new Error(`The setting of ${setting} does not exist in the UserSettings class.`);
}
if (value !== settings[setting]) {
console.log(`The setting of ${setting} changed, updating it!`);
settings[setting] = value;
}
};
Этот код не удовлетворяет компилятору TypeScript. Сбой со стороны value !== settings[setting]
, выдающий ошибку:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'UserSettings'.
No index signature with a parameter of type 'string' was found on type 'UserSettings'.
Что дает? Как я могу построить проверку во время выполнения, которая удовлетворяет компилятору TypeScript?