Что делает ключевое слово `is` в typescript?

Я столкнулся с некоторым кодом, который выглядит так:

export function foo(arg: string): arg is MyType {
    return ...
}

Я не могу искать is в документах или google, это довольно распространенное слово и отображается в основном на каждой странице.

Что делает ключевое слово в этом контексте?

Ответ 1

function isString(test: any): test is string{
    return typeof test === "string";
}

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length); // string function
    }
}
example("hello world");

Используя предикат типа "test is string" в указанном выше формате (вместо того, чтобы просто использовать логическое значение для возвращаемого типа), после вызова isString(), если функция возвращает true, TypeScript сузит тип до строки в любом блоке, защищаемом вызов функции. Компилятор будет думать, что foo - это строка в защищенном блоке ниже (и ТОЛЬКО в защищенном блоке ниже)

{
    console.log("it is a string" + foo);
    console.log(foo.length); // string function
}

Предикат типа просто используется во время компиляции. Полученный файл .js (время выполнения) не будет иметь разницы, потому что он не учитывает ТИП.

Я проиллюстрирую различия в следующих четырех примерах.

Например 1: приведенный выше пример кода не будет иметь ошибки компиляции и ошибки времени выполнения.

Например, в приведенном ниже примере кода будет ошибка компиляции (а также ошибка времени выполнения), поскольку TypeScript сузил тип до строки и проверил, что toExponential не принадлежит строковому методу.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

Например, 3: приведенный ниже пример кода не имеет ошибки компиляции, но будет иметь ошибку времени выполнения, потому что TypeScript сузит ТОЛЬКО текст до строки в защищенном блоке, но не после него, поэтому foo.toExponential не будет создавать ошибку компиляции (TypeScript не думает, что это так. тип строки). Однако во время выполнения строка не имеет метода toExponential, поэтому она будет иметь ошибку во время выполнения.

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
    }
    console.log(foo.toExponential(2));
}

Например, 4: если мы не будем использовать "test is string" (предикат типа), TypeScript не будет сужать тип в защищаемом блоке, и в приведенном ниже примере кода не будет ошибки компиляции, но будет ошибка времени выполнения.

function isString(test: any): boolean{
    return typeof test === "string";
}
function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

Вывод заключается в том, что "test is string" (предикат типа) используется во время компиляции, чтобы сообщить разработчикам, что код будет иметь ошибку во время выполнения. Для javascript, разработчики не будут знать об ошибке во время компиляции. Это преимущество использования TypeScript.

Ответ 2

Единственное, что я знаю, это один из ваших примеров: указание "предикат типа" (arg is MyType) в определяемом пользователем Type Guard

В разделе ссылка

Вот еще ссылка