Here is example:
interface SearchFunc {
(source: string, subString: string): boolean;
(source: string, subString: string, name: number): boolean;
}
const fn: SearchFunc = (source: string, subString: string, name?: number) => true
But, in your case You don't need such interface.
THis technique called overloading
Overloadings are useful, if you have some constraints.
For example, your return type is dependent on third argument:
interface SearchFunc {
(source: string, subString: string): boolean;
(source: string, subString: string, name: number): string;
}
const fn: SearchFunc = (source: string, subString: string, name?: number) => null as any
const result = fn('sdf','sdf', 2) // string
const result1 = fn('sdf','sdf') // boolean
Or next:
interface SearchFunc {
(source: string, subString: number): boolean;
(source: number, subString: string): string;
}
const fn: SearchFunc = (source: string | number, subString: string | number) => null as any
const result = fn('sdf', 2)
const result1 = fn(2, 'sdf')
const result2 = fn(2, 2) // error
const result3 = fn('2', '2') // error
Type of function allows fn(2, 2), but insterface not. Interface SearchFunc has higher priority here.
Typed arguments: (source: string | number, subString: string | number) just should be compatible with interface.
Because, according to interface source argument could be either string or number, we should also define it in function signature as string | (or) number
nameas optional:name?: number)