If you want to create a separation between defining a function and assigning properties, you can utilize a type assertion:
type Example = {
(props: any): any;
[key: string]: (props: any) => any;
}
const ZoomPanelControl = <Example>((props) => undefined);
//...
ZoomPanelControl.Item = (props) => undefined;
While you could embed the type within the type assertion, it can make the code harder to read, which is why I extracted it into the Example
type.
The compiler will still validate ((props) => undefined)
against the signature of the Example
type, ensuring type safety compared to using:
const ZoomPanelControl: Example = <any>((props) => undefined);
Additionally, you can restrict it to specific members if you don't want to allow "any string as a key"...
type Example = {
(props: any): any;
Item: (props: any) => any;
}
If you are setting this up all at once, jcalz answer provides type inference benefits (effectively giving you the type in my last code block, but automatically).