Null и undefined

Последнее обновление: 15.05.2021

Как и в JavaScript, в TypeScript есть специальные типы undefined и null, которые принимают соответствующие значения undefined и null.

Использование undefined и null зависит от параметра компиляции strictNullChecks. По умолчанию он имеет значение false и не используется, а это значит, что по умолчанию мы можем применять эти типы, как и в javascript:

let a: undefined = undefined;
let b: null = null;

Но фактически мы можем присваивать значения undefined и null переменным других типов, например, number:

let x: number = undefined;
console.log(x);
x = null;
console.log(x);
x = 5;
console.log(x);

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

В то же время отсутствие проверки для этих типов со стороны компилятора является потенциальным источников багов, поэтому нередко при компиляции применяется параметр strictNullChecks. Либо при установке флага при компиляции в консоли:

--strictNullChecks

Либо с помощью установки значения true в файле конфигурации tsconfig.json:

{
    "compilerOptions": {
        "target": "es2015",
		"noImplicitAny": true,
		"noEmitOnError": true,
		
		"strictNullChecks": true,
		
        "outFile": "app.js"
    }
}

В этом случае при попытке присвоить значение типа undefined или null переменной другого типа компилятор при компиляции выбросит ошибку. Например, при компиляции предыдущего примера кода:

let x: number = undefined;
console.log(x);
x = null;
console.log(x);
x = 5;
console.log(x);

Мы получим следующие ошибки:

strictNullChecks и undefined и null в TypeScript

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

Тем не менее нередки ситуации, когда мы точно не знаем, имеет ли какая-то переменная или параметр функции или конкретное значение или оно отсутствует. Особенно в тех случааях, когда мы получаем значение из вне, например, с помощью запроса к какому-нибудь сетевому ресурсу. В этом случае может потребоваться, чтобы переменная или параметр могли принимать значение null. И в этом случае можно использовать объединения. Например:

let userId: number|null = null;

function printId(id: number|null){
	if (id === null) {
		console.log("пользователь отсутствует");
	} else {
		console.log(`id пользователя: ${id}`);
	}
}
printId(userId)		// пользователь отсутствует
userId = 45;
printId(userId);	// id пользователя: 45

В данном случае переменная userId представляет объединение number|null, поэтому этой переменной можно присвоить как конкретное числовое значение, так и значение null.

Аналогично функция printId через параметр id может принимать как значение null, так и числовое значение.

Оператор !

Оператор ! (non-null assertion operator) позволяет указать, что объект не представляет значение null и undefined. Так, возьмем следующий пример:

const header: HTMLElement|null = document.getElementById("header");
header.innerText = "Hello Typescript!";

Встроенная функция document.getElementById() возвращает элемент веб-страницы по id, который представляет тип HTMLElement|null. То есть он может иметь значение null, если html-элемента с подобным id нет на веб-странице. Получив элемент, мы пытаемся с помощью его свойства innerText изменить его текстовое содержимое.

Вроде все нормально, однако умолчанию с включенной опцией strictNullChecks при компиляции мы получим ошибку:

non-null assertion operator в TypeScript

Чтобы избежать ошибки, используем оператор !:

const header: HTMLElement|null = document.getElementById("header");
header!.innerText = "Hello Typescript!";

Оператор ! ставится после объекта, который теоретически может принимать значение null перед обращением к его свойствам и методам:

object!.property
object!.method()

В то же время надо учитывать, что этот оператор не меняет значения объекта. Например, если объект имеет значение null или undefined, то данный оператор не поможет. Программа скомпилируется, но при выполнении скрипта программа все равно сгенерирует ошибку:

const header: HTMLElement|null = null;
header!.innerText = "Hello Typescript!";

Поэтому рекомендуется применять данный оператор, когда мы знаем, что объект не равен null или undefined.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850