There is a JavaScript function that I am working with:
const fn = (cb, param) => {
cb(param);
};
This function is meant to be called in two ways within TypeScript:
const cb0 = () => {};
fn(cb0);
const cb1 = (param: string) => { };
fn(cb1, 'str')
The expectations of the fn
function are accurately described by this type:
interface IFn {
(cb: (param: string) => void, param: string): void;
(cb: () => void): void;
}
fnI(cb0); // ok
// fnI(cb1); // correctly does not compile, callback needs an argument
fnI(cb1, 's'); // ok
It checks types at the caller sites. However, I am facing issues converting fn
to TypeScript without needing a type cast. Additionally, TypeScript seems to struggle with inferring argument types due to the overload declarations in IFn
. The closest workaround I could come up with is:
const fn: IFn = <IFn>((cb: (param?: string) => void, param?: string) => {
cb(param);
});
The issue arises when the implementation signature becomes less restrictive and violates the assertions defined in IFn
, but TypeScript fails to detect this violation.
const fn: IFn = <IFn>((cb: (param?: string) => void, param?: string) => {
cb(param === undefined ? 'some other string' : undefined);
});
Therefore, my question is:
Is there a way to define the signature of fn
or IFn
so that TypeScript can catch violations within the implementation like the one mentioned above?
I want to address these issues without resorting to runtime checks.