Reputation: 3374
I have recently enabled strictNullChecks our code. I would like to write an assertion helper that can be used inline for places where we should not have a null but the type still has null as a possible value.
Something like:
doSomething() {
assertNonNull(this.obj); // throws exception if null
this.obj.doMore();
}
I know I could do this with a this.obj!.doMore() but I would like to have the runtime assertion to verify it and then have typescript know that past that assertion the type union does not contain null anymore.
Is it possible to write a helper function like this? So far I can't seem to come up with anything.
Upvotes: 1
Views: 373
Reputation: 51769
You could make assertNonNull
to return its argument, appropriately typed when it's non-null, or throw otherwise:
function assertNonNull<T>(x: T | null | undefined): T {
if (x === null || x === undefined) {
throw new Error('non-null assertion failed');
} else {
return x;
}
}
Then you can use it like this:
class Foo {
obj: { doMore() } | null;
doSomething() {
assertNonNull(this.obj).doMore();
}
}
Upvotes: 2
Reputation: 164397
No, that's currently not possible (as far as I'm aware), as the language has no support for error throwing.
What you can do is:
class MyClass {
private obj: { doMore(): void } | null;
doSomething() {
if (assertNonNull(this.obj)) {
this.obj.doMore(); // this.obj is not null here
}
}
}
function assertNonNull(obj: { doMore(): void } | null): obj is { doMore(): void } {
return obj != null;
}
Alternitvely you can do this instead:
doSomething() {
if (!assertNonNull(this.obj)) {
throw new Error("obj is null");
}
this.obj.doMore(); // this.obj is not null here
}
But you cannot have type guard based on throwing an error.
It should be possible if a feature I requested for will be added: throws clause and typed catch clause.
You can add your scenario to the issue, it shows another usage for it.
Upvotes: 2