The function's return type is determined by what you want it to return.
One approach is to modify ExpectedReturnType
to match your desired output, and ensure that your cases are of that type or functions with an arity of 0 that return the expected type.
interface ExpectedReturnType {}
// Each case can be a function that generates the return type
// or the type itself
type CaseType = ExpectedReturnType | (() => ExpectedReturnType);
const switchcase = (
value: any,
cases: { [key: string]: CaseType },
defaultCase: CaseType
): ExpectedReturnType => {
const valueString = String(value);
const result = valueString in cases ? cases[valueString] : defaultCase;
return typeof result === "function" ? result() : result;
};
You can also utilize generics:
function switchcase<T, U = T | (() => T)>(
value: any,
cases: { [key: string]: U },
defaultCase: U
): T {
const valueString = String(value);
const result = valueString in cases ? cases[valueString] : defaultCase;
return typeof result === "function" ? (result as Function)() : result;
}
// Implementation example:
const cases = { foo: "bar", whee: () => "yay" };
switchcase("foo", cases, "bar");
// Another example using specified type:
switchcase<string>("foo", cases, "bar");
Typescript should infer T
from the parameters passed, but you can explicitly specify it as switchcase<SomeType>(...)
if needed.