Call Signatures

function call signatures can express parameter types, this types (see “Typing this”), return types, rest types, and optional types.

First, you explain the types of your functions and then you implement the code.

// Not a call signature
const add = (a: number, b: number) => a + b

// Call signature
type Add = (a: number, b: number) => number;
const add: Add = (a, b) => a + b

Overloading

When a function has multiple call signatures.

// Terrible example
type Add = {
		(a: number, b: number): number,
		(a: number, b: string): number
}

const add: Add = (a, b) => {
		if(typeof b === "string") return a
		return a + b
}
// string
Router.push("/home")

// object
Router.push({
		path: "/home"
		state: 1 
})
type Config = {
		path: string,
		state: number
}

// ⭐ Overloading
type Push = {
		(path: string): void,
		(config: Config): void
}

const push:Push = (config) => {
		if(typeof config === "string") {
				console.log(config)
		} else {
				console.log(config.state)
		}
}
type Add = {
		(a: number, b: number): number,
		(a: number, b: number, c: number): number
}

const add: Add = (a, b, c?: number) => {
		if(c) return a + b + c
		return a + b
}

Generic

A generic is like a placeholder for your types so instead of writing a concrete type.