Почему любой может быть назначен каждому типу в TypeScript - PullRequest
0 голосов
/ 18 июня 2020

Это философский вопрос о структуре типов в 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, но это не так.

1 Ответ

3 голосов
/ 18 июня 2020

В документации по любому состоянию, что any используется для «описания типа переменных, которые мы не знаем»

Начиная с TypeScript 3.0, вы должны использовать unknown для описания таких типов.

any - это артефакт из прошлого, и вы не должны использовать его, за исключением редких крайних случаев, когда вы не можете использовать unknown. Есть несколько (загадочных).

Решение

function f(): string {
    if (Math.random() > 0.5) {
        return 'a real string';
    }
    var x: unknown = null;
    return x; // Compile-time error: "Type 'unknown' is not assignable to type 'string'.(2322)"
}
...