В этом отличном сообщении в блоге объясняется, что это функция, а не ошибка. Я процитирую здесь большой кусок (курсив добавлен):
Пример
let a: number | null = 42
makeSideEffect()
a // is `a` still a number?
function makeSideEffect() {
// omitted...
}
...
Можно спросить [the] компилятор, чтобы определить, что делает makeSideEffect
, поскольку мы можем предоставить источник функции. Однако это практически невозможно из-за внешней функции и (возможно, полиморфной c) рекурсии. Компилятор попадет в бесконечные циклы, если мы дадим ему указание вывести произвольные глубокие функции, как проблему остановки как таковую. последовательная стратегия. Естественно, у нас есть две альтернативы:
- Предположим, что каждая функция не имеет соответствующего побочного эффекта : например, присваивание типа
a = null
. Мы называем это optimisti c. - Предположим, каждая функция имеет побочный эффект. Мы называем эту стратегию pessimisti c.
Spoiler: TypeScript использует стратегию optimisti c.
Еще один короткий отрывок:
Никакое ключевое слово не скажет компилятору [], будет ли функция обратного вызова вызываться немедленно , ни анализ c не скажет поведение функция: setTimeout
и forEach
одинаковы с точки зрения компилятора.
Таким образом, следующий пример не будет компилироваться.
var a: string | number = 42 // smart cast to number
someArray.forEach(() => {
a.toFixed() // error, string | number does not have method `toFixed`
})
Вот и все. В сообщении также объясняется, что нет решения , чтобы заставить TypeScript распознавать побочные эффекты функции forEach
или любой другой функции, кроме немедленно вызываемых функций. Это означает, что вы можете:
- Использовать обычный для l oop вместо
forEach
, что приводит к правильному выводу окончательного canActivate
как boolean
а не true
. - По возможности используйте немедленно вызываемые функции. Или ...
- Придерживайтесь парадигм функционального программирования (FP) при использовании функций в стиле FP таких как
map
, filter
, forEach
и т.д. c. Это означает стремление к неизменности, отсутствие побочных эффектов и т. Д.
В общем, плохие новости. Надеюсь, что в будущем TypeScript получит какую-то функцию, которая позволит нам предупреждать компилятор, когда функция изменяет определенную переменную - по крайней мере, чтобы предотвратить преждевременное предположение, что то, что изначально было истинным, всегда останется таковым.