Introduction: Why Documentation Is Not a Boring Obligation, But a Superpower
\n\nImagine: you return to your project after six months. You open the file with the authorization logic — and see a sea of TypeScript code. The types are there, the interfaces are defined, but what does this function do? Why is the parameter called opts and what fields does it have? Sound familiar?
Documentation in TypeScript is not just "comments for the sake of it." It is a tool that turns your code into an understandable story. Good documentation saves hours of debugging, speeds up onboarding for newcomers, and makes your API friendly. In this article, we will break down the best practices for documenting TypeScript projects: from basic JSDoc comments to advanced documentation generation with TypeDoc. Let's go!
\n\n1. JSDoc and TSDoc: The Foundation of Your Documentation
\n\nTypeScript inherited the popular JSDoc format from JavaScript, and then the community developed TSDoc — a standardized syntax for TypeScript. If you are writing a library or API, TSDoc is your choice. It is stricter and integrates better with editors and documentation generators.
\n\nBasic TSDoc Tags
\n\nHere is the minimum that every developer should know:
\n\n- \n
@param— description of a function parameter \n @returns— what the function returns \n @throws— what exceptions it can throw \n @example— usage example \n @deprecated— marking deprecated code \n
/**\n * Calculates the discount on a product considering a promo code.\n * \n * @param price - The original price of the product (must be greater than 0)\n * @param discountPercent - The discount percentage (from 0 to 100)\n * @param promoCode - A promo code that can increase the discount\n * @returns The final price after applying the discount\n * @throws {Error} If the price or percentage is invalid\n * \n * @example\n * // Example: 20% discount on a product costing 1000 rubles\n * const finalPrice = calculateDiscount(1000, 20, 'SUMMER');\n * console.log(finalPrice); // 800\n */\nfunction calculateDiscount(\n price: number,\n discountPercent: number,\n promoCode?: string\n): number {\n if (price <= 0 || discountPercent < 0 || discountPercent > 100) {\n throw new Error('Invalid parameters');\n }\n \n let discount = discountPercent;\n if (promoCode === 'SUMMER') {\n discount += 10; // additional discount\n }\n \n return price * (1 - discount / 100);\n}\n\n\nTip: Always describe edge cases. If a parameter can be undefined, specify this in the description. TypeScript types are good, but human language adds context.
2. Document Types and Interfaces
\n\nOne of the main features of TypeScript is its powerful type system. But even the strictest type will not explain the purpose of a field. Document interfaces as thoroughly as functions.
\n\n/**\n * Configuration for connecting to an external weather API.\n */\ninterface WeatherApiConfig {\n /** The base URL of the API (e.g., https://api.weather.com) */\n baseUrl: string;\n \n /** The authentication key obtained from the provider */\n apiKey: string;\n \n /** \n * The number of seconds to wait for a response from the server.\n * Default is 5 seconds.\n */\n timeout?: number;\n \n /**\n * The API version. If not specified, the latest stable version is used.\n * @deprecated Use the `version` field in the URL\n */\n apiVersion?: string;\n}\n\n\nNotice: for timeout, we specified the default value directly in the comment. This saves the developer from having to dig into the source code or tests.
3. Documentation Generation: Turning Comments into a Website
\n\nWriting comments is half the battle. You need to be able to turn them into convenient documentation. For TypeScript, the best tool is TypeDoc. It parses your TSDoc comments