I have a utility function which I use for throwing different kinds of errors in an organized way. It always throws an error. However, Typescript is not smart enough to use this for narrowing:
interface A {
x: {
a?: string;
}
}
const g = (s: A): string => {
if (!s.x.a) {
throw Error("mess");
}
return s.x.a // compiles just fine
}
const f = (): never => {
throw Error('message');
}
const gg = (s: A): string => {
if (!s.x.a) {
f()
}
return s.x.a // ERROR: can be undefined!
}
I thought returning never
will help the compiler to be smarter, but it doesn't. Is there another way or a keyword to use to achieve this?
CodePudding user response:
You can't really have f
magically make whatever condition it was called under the assertion condition, but if you pass that condition directly to f
and utilize asserts
, then you will come up with something that is similar to the built-in asserts
function from Node.js:
function f(thing: any): asserts thing {
if (!thing) throw Error('message');
}
Pretty uncanny resemblance with the real deal:
function assert(condition: any, msg?: string): asserts condition {
if (!condition) {
throw new AssertionError(msg);
}
}
CodePudding user response:
why not just return f as you know it would throw anyways and halt the execution
const gg = (s: A): string => {
if (!s.x.a) {
return f()
}
return s.x.a // ERROR: can be undefined!
}