I have a function foobar(x:string) which will not return if x is the empty string. Otherwise, it return another string.
So I can't declare it to return "never", and if I declare it to return "string", TS doesn't realise the code afterwards may not be reached
(Yes, this is a horrid design. No, I can't change it)
Sometimes, I need to use it with an empty x in another function which in other branches returns a value. So something like
function f(n:number)
{
if (n==0) {
foobar("")
}
else
{
return n - 1
}
}
TS complains because not all paths return a value. So I would like to tell the compiler that foobar does not return (or, equivalently the code after it is unreachable). Making something up, something like:
function f(n:number)
{
if (n==0) {
foobar("")
/** @notreachable */
}
else
{
return n - 1
}
}
Can I do this? What else can I do? I could return something of type never, maybe, but how do I get a never "value" to return?
Have you tried function overloads:
function foobar(val: string): string;
function foobar(val: ''): never;
function foobar(val: string): string {
if (val === '') {
// while (true) {
// console.log('Infinite loop also works fine');
// }
throw new Error('never returns');
} else {
return 'new value';
}
}
function f(n: number) {
if (n === 0) {
foobar('');
} else {
return n - 1;
}
}
Update I think similar approach will work for empty objects as well:
interface NoProps {
[a: string]: never;
}
interface X {
a?: string;
}
function foobar(val: NoProps): never;
function foobar(val: X): string;
function foobar(val: NoProps | X): string {
if (val.a === undefined) {
throw new Error('never returns');
} else {
return 'new value';
}
}
function f(n: number) {
if (n === 0) {
foobar({});
} else {
return n - 1;
}
}