Complete TS Documentation
website·Indexed 30 days ago
https://complete-ts.github.ioA collection of linting tools and utilities for TypeScript and Markdown, including eslint-plugin-complete for type-aware ESLint rules, markdownlint-rule-complete for custom Markdown linting rules, and markdownlint-config-complete.
What's inside Complete TS
- Complete is a collection of packages designed to make working with TypeScript easier. The ecosystem includes tools for project bootstrapping, shared configurations for TypeScript and ESLint, helper functions for Node.js and general TypeScript projects, and Markdown linting rules.
Overview of complete-common library
complete-commonis a zero-dependency TypeScript library providing basic helper functions and types suitable for any TypeScript project, including React and Node.js environments. It includes utilities for arrays, assertions, enums, maps, math, objects, random values, sets, sorting, strings, time, tuples, type narrowing, and various utility types.Overview of complete-node library
complete-node is a utility library providing helper functions for Node.js TypeScript projects. While designed for Node.js, it is also compatible with other JavaScript runtimes including Deno and Bun.Understand the project structure generated by complete-cli
When initializing a project with
complete-cli init, the following directory structure and files are created:src/: The TypeScript source directory. All project source code should reside here.dist/: The compiled output directory. TypeScript files fromsrcare converted to JavaScript here during the build process.scripts/: Contains TypeScript-based project scripts (e.g., build and lint) to avoid using Bash or Python.node_modules/: Contains project dependencies. This directory is automatically excluded via.gitignore.
Configure target binaries for compileToSingleFileWithBun
When usingcompileToSingleFileWithBun, you can optionally specify atargetparameter to define the binary format of the output executable. If omitted, Bun defaults to the current system's architecture. For a list of supported target formats, refer to the Bun documentation on executables.Understand comment types and plugin behavior in eslint-plugin-complete
The
eslint-plugin-completeplugin distinguishes between three types of comments and applies rules differently based on their type:- Line Comments (
//):- Trailing line comments (on the same line as code) are ignored by the plugin's rules to allow for quick, informal annotations.
- Leading line comments (on their own line) are subject to formatting rules.
- Block Comments (
/* ... */): These are generally ignored by the plugin as they are typically used to comment out blocks of code. - JSDoc Comments (
/** ... */): These are treated as official documentation. The plugin enforces strict formatting and grammatical rules (such as complete sentences) because this content is often extracted by tools like TypeDoc.
- Line Comments (
Enforce postfix increment and decrement with complete/prefer-postfix-plusplus
The
complete/prefer-postfix-plusplusrule requires the use of postfix operators (i++andi--) instead of prefix operators (++iand--i). This promotes code uniformity and avoids arcane syntax that can confuse readers, as prefix operators are rarely needed in JavaScript/TypeScript.This rule requires type information to function correctly. It is recommended to use this rule in conjunction with
no-unsafe-plusplusto ensure that cases where prefix operators are functionally necessary are identified and handled before converting the remaining instances to postfix.// ❌ Bad ++foo; --foo; // ✅ Good foo++; foo--;Prevent use of horizontal rules with no-horizontal-rules
Theno-horizontal-rulesrule disallows the use of horizontal rules in Markdown files. Horizontal rules are discouraged because they provide visual structure without describing the semantic relationship between sections. Instead, use headings to organize content. This rule automatically removes horizontal rules when applied.<!-- Bad --> First section --- Second section <!-- Good --> ## First Section ## Second SectionUpdate package.json dependencies using updatePackageJSONDependencies
The
updatePackageJSONDependenciesfunction runsnpm-check-updatesto update dependencies in apackage.jsonfile. If updates are found, the project's package manager is automatically invoked to install them.To prevent specific packages from being updated (lock versions), create a
package-metadata.jsonfile in the same directory as thepackage.jsonand specify the packages to lock.function updatePackageJSONDependencies( filePathOrDirPath?, installAfterUpdate?, quiet?, packagesWithoutCooldown?, ): Promise<boolean>;// Example package-metadata.json to lock a version: { "dependencies": { "react": { "lock-version": true, "reason": "Docusaurus does not support the latest version of React." } } }
Install eslint-plugin-complete manually
To useeslint-plugin-completewithout thecomplete-lintmeta-package, install the plugin along with its peer dependencieseslintandtypescriptusing your package manager.npm install --save-dev eslint typescript eslint-plugin-completeEnforce immutable interfaces with complete/type-declaration-immutability
Thecomplete/type-declaration-immutabilityrule enforces that all properties within an interface are immutable. This rule is enabled by default in therecommendedconfiguration and requires TypeScript type information to function. Unlike similar rules in other plugins, this rule is not configurable and requires every interface to be fully immutable. Type aliases are ignored, and interface naming does not affect enforcement. Deeply immutable types such asReadonlyMap,ReadonlySet, and read-only arrays are considered compliant.// ❌ Bad: Property is mutable interface Foo { bar: string; } // ✅ Good: Property is readonly interface Foo { readonly bar: string; }Prevent using Object methods with Map and Set via complete/no-object-methods-with-map-set
The
complete/no-object-methods-with-map-setrule disallows the use ofObject.entries,Object.keys, andObject.valueswhen the target is aMaporSet. Using theseObjectmethods on maps or sets is typically a bug and will not iterate over the collection's entries as expected. Instead, use the built-in.entries(),.keys(), and.values()methods provided by theMapandSetprototypes.This rule is enabled by default in the
recommendedconfiguration and requires TypeScript type information to function.declare const myMap: Map<string, string>; // ❌ Bad: Using Object methods on a Map for (const [key, value] of Object.entries(myMap)) {} for (const key of Object.keys(myMap)) {} for (const value of Object.values(myMap)) {} // ✅ Good: Using Map prototype methods for (const [key, value] of myMap.entries()) {} for (const key of myMap.keys()) {} for (const value of myMap.values()) {} declare const mySet: Set<string>; // ❌ Bad: Using Object methods on a Set for (const entry of Object.entries(mySet)) {} for (const key of Object.keys(mySet)) {} for (const value of Object.values(mySet)) {} // ✅ Good: Using Set prototype methods for (const entry of mySet.entries()) {} for (const key of mySet.keys()) {} for (const value of mySet.values()) {}