I have some TypeScript code that looks essentially like this:
if( ... )
result = $(document.createElement("div")) ;
} else if( ... ) {
result = $(document.createElement("div")) ;
} else {
assert.unreachable( "Unknown label in buildHTML.") ;
}
result.attr( "data-childNumber", childNumber.toString() ) ;
The return type of assert.unreachable
is never
.
There is an error on the last line:
Variable 'result' is used before being assigned.
It seems to me that the never
result from assert.unreachable
should tell the compiler that there is no path out of the else
part.
I know that I can suppress the error by adding throw null;
at the end of the else
, but this seems inelegant.
A similar problem comes up in the definition of unreachable
. It looked like this
export function unreachable( message? : string ) : never {
if( message===undefined ) message = "Unreachable code reached." ;
else message = "Unreachable code reached: "+message ;
raiseTheAlarm( message ) ;
}
where the result type of raiseTheAlarm
is never
. In this case, I got an error:
A function returning 'never' cannot have a reachable end point.
I fixed this by adding a return
keyword before the call to raiseTheAlarm
. This looks a bit odd. (Of course, throw null;
after the call would also have worked.)
Is there a better way to tell the compiler that a point in the code is not reachable?
It seems to me that the never result from
assert.unreachable
should tell the compiler that there is no path out of the else part.
It works the other way round. When compiler detects that some path is unreachable, it infers never
type for variables referenced in that path, if it can. You can use it to enforce that your code handles all possible values for enum or union type, as explained here.
However, compiler does not use information that some path is unreachable when it checks that variable is not used before it's initialized. The solution is simple - you can assign never
value to that variable in the unreachable path. As explained in the answer linked above, never
was made assignable to any other type specifically for this purpose.
if( ... )
result = $(document.createElement("div")) ;
} else if( ... ) {
result = $(document.createElement("div")) ;
} else {
result = assert.unreachable( "Unknown label in buildHTML.") ;
}
result.attr( "data-childNumber", childNumber.toString() ) ;
A problem with your unreachable
function is fixed in the same way - it should have
return raiseTheAlarm( message ) ;
as the last statement.
There are at least three options
(a)
else {
return assert.unreachable( "Unknown label in buildHTML.") ;
}
(b) (from @artem's answer)
else {
result = assert.unreachable( "Unknown label in buildHTML.") ;
}
(c)
else {
assert.unreachable( "Unknown label in buildHTML.") ;
throw null ;
}
I went with option (a).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With