14

В TypeScript, что означает оператор ! (восклицательный знак) при разыменовании члена?

10

При изучении исходного кода правила tslint я наткнулся на следующую строку:

if (node.parent!.kind === ts.SyntaxKind.ObjectLiteralExpression) {
    return;
}

Обратите внимание на оператор ! после node.parent. Интересно!

Сначала я попытался скомпилировать файл локально с установленной у меня версией TypeScript (1.5.3). Полученная ошибка указывала на точное место с восклицательным знаком:

$ tsc --noImplicitAny memberAccessRule.ts 
noPublicModifierRule.ts(57,24): error TS1005: ')' expected.

Затем я обновился до последней версии TypeScript (2.1.6), и компиляция прошла без проблем. Таким образом, это, похоже, функция версии TS 2.x. Но транспиляция полностью проигнорировала восклицательный знак, в результате чего получился следующий JavaScript:

if (node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) {
    return;
}

Мои поиски в Google пока не принесли результатов.

Что такое оператор восклицательного знака в TypeScript и как он работает?

5 ответ(ов)

4

Ответ Луи отличный, но я решил кратко подвести итоги:

Оператор bang (!) говорит компилятору временно ослабить требование "не null", которое он мог бы предъявить. Он сообщает компилятору: "Как разработчик, я знаю лучше, чем ты, что эта переменная сейчас не может быть null".

0

Оператор утверждения о ненулевом значении

С помощью оператора утверждения о ненулевом значении мы можем явно указать компилятору, что выражение имеет значение, отличное от null или undefined. Это может быть полезно в тех случаях, когда компилятор не может точно определить тип, но у нас есть больше информации, чем у компилятора.

Пример

Код на TypeScript

function simpleExample(nullableArg: number | undefined | null) {
   const normal: number = nullableArg; 
    // Ошибка компиляции: 
    // Тип 'number | null | undefined' не может быть присвоен типу 'number'.
    // Тип 'undefined' не может быть присвоен типу 'number'.(2322)

   const operatorApplied: number = nullableArg!; 
    // Компилируется без ошибок, потому что мы говорим компилятору, что null и undefined исключены 
}

Скомпилированный JS код

Обратите внимание, что в JS нет концепции оператора утверждения о ненулевом значении, так как это функция TypeScript.

"use strict";
function simpleExample(nullableArg) {
    const normal = nullableArg;
    const operatorApplied = nullableArg;
}

Таким образом, использование оператора ! позволяет избежать ошибок компиляции, когда вы уверены, что значение переменной не будет равным null или undefined.

0

Краткий ответ

Оператор утверждения о ненулевом значении (!) помогает компилятору понять, что я уверен, что эта переменная не является ни null, ни undefined.

let obj: { field: SampleType } | null | undefined;

... // какой-то код

// тип sampleVar - SampleType
let sampleVar = obj!.field; // мы сообщаем компилятору, что уверены, что obj не null и не undefined, поэтому тип sampleVar - SampleType
0

Да, вы правы, оператор ! и NonNullable выполняют схожие задачи, но есть некоторые различия в использовании.

В вашем примере переменная ns имеет тип string | null. Когда вы используете оператор !, вы утверждаете, что ns не равен null в момент использования. Таким образом, переменная s1 получает тип string, потому что вы уверяете TypeScript, что в данный момент ns содержит строку.

let s1 = ns!;
//  ^? let s1: string

С другой стороны, когда вы используете as NonNullable<typeof ns>, вы фактически преобразуете ns в тип string, не давая никакого утверждения о том, что значение не null на момент выполнения. Это будет работать только в том случае, если ns действительно не null, но в отличие от оператора !, это не изменяет способ проверки типов во время выполнения.

let s2 = ns as NonNullable<typeof ns>;
//  ^? let s2: string

Итак, в итоге, если вы уверены, что значение не null, можете использовать !, а если хотите применить преобразование типов, не устанавливая такие предубеждения, используйте as NonNullable. Однако будьте осторожны с использованием !, так как если значение null, это приведет к ошибкам во время выполнения.

0

Не допускающий null (Non-Nullable)

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

let myElement: HTMLElement | null = document.getElementById('myElement');

// Без оператора утверждения о не-null
// Ошибка компиляции: Объект может быть 'null'.
myElement.innerHTML = 'Hello, world!';

// С оператором утверждения о не-null
myElement!.innerHTML = 'Hello, world!';

В приведенном выше примере, если вы не используете оператор утверждения о не-null (!), TypeScript не позволяет вам получить доступ к свойству innerHTML, так как myElement может быть равен null. Однако, используя оператор !, вы сообщаете компилятору, что уверены, что myElement не равен null в данный момент, и, следовательно, доступ к свойству innerHTML может быть выполнен без ошибок. Однако будьте осторожны с использованием оператора !, так как это может привести к ошибкам выполнения, если переменная на самом деле будет равна null.

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