I will start from what is function in JS/TS. Function is an object, that means that as any other objects function can have methods and properties. This is even visible in base function object, as it has methods like apply or bind. In any given moment you can attach property to any function. Consider
const f = (a:string) => a
f.prop = 1;
// take a type from f
type F = typeof f;
It is full valid TS code. And if we ask what type above function has it will be:
type F = {
(a: string): string;
prop: number;
}
As you can see above is close to your sample code. And indeed what we have here is function object in TS, it has main definition of functions in form of (a: string): string; and other properties like prop or in your example a1.
Its not a mistake that this definition is so similar to standard object type definition, as we said function is just an object.
If your function has no other properties you can define the type in two ways:
type F1 = {
(props: string):number;
}
type F2 = (props: string) => number
Above F1 and F2 definition are equal, but the first one gives opportunity to append additional properties to function object, where the second does not allow on such.
How now we can create valid object of our function with property, consider following snippet:
interface F1 {
(props: string):number;
a1: number;
}
// below preparation of object by temporary f1
const f1 = (props: string) => 1
f1.a1 = 2;
const a: F1 = f1; // a is valid value type F1
In your example a1 is optional so it doesn't need to be provided, that said such definition is valid:
const f1: F1 = (props: string) => 1
Ok, the last thing is object with func property, it is really a different thing.
const obj = {
func: (p: string): number => (10+2),
};
type Obj = typeof obj;
If we check what is Obj type it is:
type Obj = {
func: (p: string) => number;
}
So it is different type, it says we don't have function object, but an object with method func. We can easily compare both types
type FunctionType = {
(props: string):number;
}
const f: FunctionType = props => 1
type ObjectWithMethodType = {
func: (props: string) => number
}
const obj: ObjectWithMethodType = {
func: props => 1
}
I hope this explanation helps.