Objects and functions are fundamentally the same thing, but typings help us disambiguate between their functionality.
Consider this:
const foo1: { (): string } = () => "";
The variable foo
has a type of object
, but that object is callable ... it's a function, and it can indeed be called, but you can't go setting a property called bar
on it.
foo1(); // This works
foo1.bar = 5; // This, not so much.
Also consider this:
const foo2: { bar?: number; } = {};
The variable foo
has a property called bar
on it. That property can be set, but the object can't be called, as it's not typed as callable.
foo2.bar = 5; // This works
foo2(); // This, not so much.
So, lets have a look at your original typing:
sortQuery = {}
sortQuery
is an object, but that's all that we know about it. It doesn't have any properties, it's not callable, it's just an object.
We've already seen that a function is an object, so you can assign a function to it just fine. But, you won't be able to call it, as it's not defined as callable.
const sortQuery: {} = () => ""; // This works.
sortQuery(); // This, not so much.
sortQuery.bar = 5; // Nor this.
If you have full control of the source code, then one way to solve this is to move from multiple parameters, to a single parameter with named properties:
const foo = (params: { collection: string, query: object, sortQuery: {}, cb?: Function }) => { };
foo({ collection: "", query: {}, sortQuery: {} }); // Fine
foo({ collection: "", query: {}, sortQuery: {}, cb: () => { } }); // Fine
foo({ collection: "", query: {}, cb: () => { } }); // Not Fine
This removes any ambiguity by requiring names, rather than relying on position in the function call.
sortQuery
as an object type? or is it any? – Jonas WilmssortQuery
? You could define it more specifically – Frank Modica