I have the following interfaces and types (all of which are open to change)
interface Base {
type: string;
}
interface A extends Base {
type: "A";
field: string;
}
interface B extends Base {
type: "B";
query: string;
}
interface C extends Base {
type: "C";
equal: number;
}
type BaseExtensions = A | B | C;
interface BaseWrapper<R extends BaseExtensions> {
idType: string;
base: R;
}
interface And {
type: "AND";
rules: Array<BaseWrapper<any>>;
}
interface Or {
type: "OR";
rules: Array<BaseWrapper<any>>;
}
type Rule<R extends BaseExtensions> = BaseWrapper<R> | And | Or
What I would like to do is write the following function:
function doAThingBasedOnTheRuleType(rule: Rule<any>): Thing {
if (isAnd(rule)) {
return DoAndThing(rule);
}
if (isOr(rule)) {
return DoOrThing(rule);
}
if (isA(rule.base)) {
return DoAThing(rule);
}
if (isB(rule.base)) {
return DoBThing(rule);
}
if (isC(rule.Base)) {
return DoCThing(rule);
}
// error, [ts] Function lacks ending return statement and return type does not include 'undefined'.
}
I would expect that Rule starts out as And | Or | BaseWrapper<A> | BaseWrapper<B> | BaseWrapper<C> which should get narrowed down one by one. However, I get the error // error, [ts] Function lacks ending return statement and return type does not include 'undefined'.
1- Why is TS not able to infer the types? 2- How do I fix it?
I'm on TS 2.5.2