TypeScript has two concepts: type annotations and type inference. Type annotations involve explicitly specifying the type of a parameter or variable, while type inference occurs when TypeScript automatically determines the type based on the implementation.
TypeScript has a structural type system, which means that types are compatible based on their shape or structure rather than their names. This allows you to interchangeably use types with different names but identical properties. You can assign one type to another if they share the same properties, including optional properties.
Branded types in TypeScript can help catch programming errors early by ensuring that values meet certain criteria before they are used. To create a branded type, you add a readonly property to an existing type. Branded types are especially useful when combined with assertion functions, which validate inputs and assert the branded type after successful validation.
TypeScript 2.1 introduced mapped types, which allow you to create new types based on the properties of an existing type. For example, you can create a mapped type that has the same keys as an existing type, but with optional values.
If you're extending the `EventEmitter` class from Node.js and encounter the error TS2307 or TS2339, it means you're missing the Node.js type definitions. To fix this, install the typings by running `yarn add @types/node@12 --dev --tilde`. This solution has been tested with TypeScript 3.9.3 and Node.js 12.18.0 LTS.