Can I write a type guard asserting something about one or multiple sub-objects of an argument? In pseudo-code, it might look like this:
class C {
a: number?;
b: string?;
function assertInitialized() : (this.a is number) and (this.b is string) {
return this.a !== null && this.b !== null;
}
}
Background: I'd commonly use a single function to check invariants of my classes; for example, assume I have a class with some nullable fields, which get asynchronously initialized.
class DbClient {
dbUrl: string;
dbName: string;
dbConnection: DBConnection?;
…
}
This class goes through a complex asynchronous initialization process, after which dbConnection becomes non-null. Users of the class must not call certain methods until dbConnection is initialized, so I have a function assertReady:
assertReady() {
if (this.dbConnection === null) {
throw "Connection not yet established!";
}
}
This function assertReady is called at the beginning of each function that requires the DbClient to be fully initialized, but I still have to write non-null assertions:
fetchRecord(k: string) {
assertReady();
return this.dbConnection!.makeRequest(/* some request based on k */);
}
Can I give assertReady a signature that makes the ! unnecessary? I don't want to pass this.dbConnection to assertReady, because that function is typically more complex.
The only trick I'm aware of is to create an interface with the same fields as the current class, but with non-nullable types (without the ?). Then I can make a type guard that says that this is InitializedDbClient. Unfortunately that requires duplicating a large part of the class definition. Is there a better way?