Это философский вопрос о структуре типов в TypeScript.
Давайте взглянем на следующий короткий фрагмент ( доступен здесь в качестве игровой площадки ).
function f(): string {
if (Math.random() > 0.5) {
return 'a real string';
}
var x: any = null;
// Why does this type check?
return x;
}
const myString = f();
// myString has type string
// not string | any, not string | undefined, not string | null
// so I expect it to really be a string
console.log(myString.length);
// -> TypeError: null is not an object (evaluating myString.length)
Короче, у меня вопрос: почему этот пример компилируется со всеми возможными флагами строгости?
В документации на any
указано, что any
используется для «описания типа переменных, которые мы не используем. знаю ". По этой причине имеет смысл, что все типы могут быть присвоены any
, однако, почему any
может быть назначено всем другим типам?
По самой своей природе объекты с типом any
имеют неизвестные свойства, так почему их можно маршалировать в другие типы (например, string
) без предупреждения? Разве это не противоречит цели явной пометки объектов типами, когда мы знаем, что компилятор не применяет их содержимое?
Например, допустим, я хочу определить функцию, которая однозначно возвращает string
(не null
, а не undefined
, не number
, а именно string
). Есть ли способ заставить компилятор TypeScript обеспечить, чтобы каждый кодовый путь, возвращаемый этой функцией, возвращал строку? Мое предубеждение таково, что пример выше должен делать это, и что мы должны увидеть ошибку вроде any is not assignable to type string
, но это не так.