Почему оператор доступа к массиву ([]) на объектах не является ошибкой? - PullRequest
0 голосов
/ 01 октября 2018

При рефакторинге моего кода я наткнулся на странное поведение компилятора TypeScript, которого я не понимаю.

interface IPoint {
    x: number;
    y: number;
}

let a: IPoint = { x: 5, y: 10 };
let b = a[0];
console.log(b);

При компиляции этого кода я ожидаю, что компилятор выдаст ошибку, потому чтодоступа к ключу a, который определенно не существует (во время компиляции).

Почему это?Есть ли альтернативный вариант TSLint? Мне не известно, что метки [] используются на объектах как ошибка / предупреждение?

С уважением и заранее спасибо

Ответы [ 3 ]

0 голосов
/ 01 октября 2018

Я настоятельно рекомендую включить опцию компилятора --strict .Эта опция включает кучу дополнительных проверок, которые неоценимы при обнаружении ошибок.В вашем случае необходимая проверка выполняется с помощью опции --noImplicitAny:

--noImplicitAny: выдает ошибку в выражениях и объявлениях с подразумеваемым типом any.

Если вы включите это, вы увидите следующую ошибку:

let b = a[0]; // error!
// Element implicitly has an 'any' type because type 'IPoint' has no index signature.

Вы можете обнаружить, что если вы включите режим --strict, появится множество других ошибок.Это раздражает, но, как правило, это хорошие ошибки, с которыми вам следует иметь дело, и даже когда появляются ложные срабатывания, обработка этих ошибок улучшит ваш код.

Надеюсь, что это поможет;удачи!

0 голосов
/ 01 октября 2018

В JavaScript [] - это не только оператор индекса массива, это также средство доступа к свойству , что означает, что его можно использовать для доступа к свойствам объекта, например

const animal = {
  legCount: 4
};

console.log(animal.legCount); // 4
console.log(animal['legCount']); // 4

Как обсуждено здесь , TypeScript неявно предоставляет всем индексам тип any:

JavaScript позволяет индексировать любой объект.Компилятор TypeScript не может статически знать, что тип проверял все это, например var name = getName(); x[name];.поэтому ему присваивается тип any.

Чтобы добавить некоторый уровень защиты, вы можете попробовать добавить сигнатуру индекса и указать ожидаемые типы.

interface IPoint {
    x: number;
    y: number;
    [key: string]: number; // This object will contain only number properties.
}
0 голосов
/ 01 октября 2018

С настройками компилятора по умолчанию машинный ввод позволит индексировать операции с любым объектом с любым ключом (и результат будет иметь тип any).Чтобы сделать это ошибкой, используйте опцию компилятора noImplicitAny.

...