Могу ли я написать защиту типа, утверждающую что-то об одном или нескольких подобъектах аргумента? В псевдокоде это может выглядеть так:
class C {
a: number?;
b: string?;
function assertInitialized() : (this.a is number) and (this.b is string) {
return this.a !== null && this.b !== null;
}
}
Предыстория: я обычно использую одну функцию для проверки инвариантов своих классов; например, предположим, что у меня есть класс с некоторыми полями, допускающими значение NULL, которые инициализируются асинхронно.
class DbClient {
dbUrl: string;
dbName: string;
dbConnection: DBConnection?;
…
}
Этот класс проходит сложный асинхронный процесс инициализации, после которого dbConnection
становится ненулевым. Пользователи класса не должны вызывать определенные методы, пока dbConnection не будет инициализирован, поэтому у меня есть функция assertReady
:
assertReady() {
if (this.dbConnection === null) {
throw "Connection not yet established!";
}
}
Эта функция assertReady
вызывается в начале каждой функции, которая требует полной инициализации DbClient
, но мне все равно приходится писать ненулевые утверждения:
fetchRecord(k: string) {
assertReady();
return this.dbConnection!.makeRequest(/* some request based on k */);
}
Могу ли я дать assertReady
подпись, которая сделает !
ненужным? Я не хочу передавать this.dbConnection
в assertReady
, потому что эта функция обычно более сложная.
Единственный известный мне трюк — создать интерфейс с теми же полями, что и у текущего класса, но с ненулевыми типами (без ?
). Затем я могу сделать защиту типа, которая говорит, что this is InitializedDbClient
. К сожалению, это требует дублирования большей части определения класса. Есть ли способ лучше?