Машинопись: использование Map<> с strictNullChecks
Учитывая следующий простой класс:
class Observer {
private subscribers: Map<string, Array<((data: any) => void)>> = new Map();
public subscribe(event: string, callback: (data: any) => void) {
if (!this.subscribers.has(event)) {
this.subscribers.set(event, []);
}
this.subscribers.get(event).push(callback); //tsc says: Object is possibly 'undefined'
}
}
Кроме того, в tsconfig.json флаги strictNullChecks
а также strict
включены
Хотя subscribers
проверяется наличие ключа текущего события, компилятор машинописного текста жалуется на сообщение об ошибке, показанное выше (this.subscribers.get(event)
возможно не определено).
Если я не совсем неправ, this.subscribers.get(event)
никогда не может быть undefined
в этом случае.
Как я могу избавиться от этого сообщения?
2 ответа
Печатать Map
прямо заявляет, что get
может привести к undefined
:
interface Map<K, V> {
...
get(key: K): V | undefined;
...
}
Вот почему вы получаете сообщение об ошибке с параметром strictNullChecks.
Вы можете использовать оператор ненулевого утверждения, чтобы сообщить компилятору, что вы уверены, что он действительно имеет значение:
this.subscribers.get(event)!.push(callback);
Другой вариант (на мой взгляд, лучший) - это рефакторинг вашего кода следующим образом:
public subscribe(event: string, callback: (data: any) => void) {
let callbacks = this.subscribers.get(event);
if (!callbacks) {
callbacks = []
this.subscribers.set(event, callbacks);
}
callbacks.push(callback);
}
Почему бы не написать новый интерфейс/класс, который не допускал бы неопределенных значений?
interface StrictMap<K, V> {
...
get(key: K): V /* `| undefined` -> main diff. with `Map` native interface: The values can't be undefined */;
...
}
PS: На самом деле, я искал такой интерфейс/класс, когда нашел этот пост SO;)