Since type narrowing works in so many other cases I expected an instance method to also narrow the type of this
like the type annotations would seem to suggest, but this only works in other methods on the same type, not outside the class. Is there another way to make the instance method assertion work or do I just need to resign myself to exporting helper assert functions?
class box<T> {
constructor(public value: T){}
check(): this is box<string> {
return typeof this.value == 'string';
}
assert(): asserts this is box<string> {
if (typeof this.value != 'string') throw new Error();
}
private test() {
this.assert();
// type correctly narrowed
this.value.substring(0);
}
}
function make() : box<string> | box<number> {
return new box('a');
}
function assert(b: box<string> | box<number>): asserts b is box<string> {
if (typeof b.value != 'string') throw new Error();
}
const b = make();
if (b.check()) {
// type correctly narrowed
b.value.substring(0);
}
b.assert();
// type not narrowed (substring does not exist on type 'string | number')
b.value.substring(0);
assert(b);
// type correctly narrowed
b.value.substring(0);