In TypeScript, there are different ways to write function types: function type expressions, call signatures, construct signatures, or generic functions.
These features enable you to write more flexible and robust code by allowing for the possibility of "undefined" or "null" values, and by providing default values when no value is passed in.
Declaration merging allows multiple declarations of the same name to be merged into a single definition. This can be done for interfaces, namespaces, enums and other types.
By using `keyof`, you can define types that depend on the properties of an object without actually knowing the specific property names in advance.
Conditional types are a feature of the TypeScript language that allow for the creation of types that depend on the evaluation of other types.
A special kind of union types that can be narrowed down using a common property that each member of the union contains.
You can avoid repeating yourself by using mapped types to transform an existing type into a new type by mapping over its properties with some modifications.
Type narrowing allows you to access properties and methods that are only available on certain types, and also helps TypeScript to catch errors and bugs at compile time.