Documentation
Intro
Rizing code should be self-documenting in the sense that code workflow and expression are apparent and easily understandable simply through the use of good coding principles. This means that inline comments throughout the codebase should be minimal and only present to explain why
something is being done, rather than how
- the how should be expressed through CLEAN readable code.
Although inline comments should be avoided, documentation comments are a must.
Comments Are Not Documentation
Code documentation and code comments aren't the same thing. Code comments are inline comments that provide contextual information to specific code, as aforementioned. However, code documentation serves as a conceptual maintenance manual for your software. Code documentation is extremely important for code that is ever going to be reused. As such, all publicly accessible code (exported code) must be thoroughly documented.
General Rules
Sentence Case
Documentation should be written in sentence case. This means each description should be a complete sentence starting with a capitalized letter and ending with a period.
Descriptions
At a minimum, descriptions should be given for all exported items (classes, methods, properties, etc).
/** This is a short description. */
export function someFunction() {}
// or for longer descriptions...
/**
* This is a longer description that looks better
* with a multi-line JSdoc format.
*/
export function someFunction() {}
TypeScript
TypeScript already provides definitions for the types present in your code and types are therefore not needed in the documentation. Furthermore they are prohibited as the presence of them require additional maintenance to keep them in sync with the actual code. The following examples can be used as definitive guides on how to properly document TypeScript code.
Functions
/**
* Returns the average of an array of numbers.
*
* @example average([1, 2, 3]) // result: 2
* @param values A list of numbers to average together.
* @returns The average of the passed in numbers.
*/
export function average(values: number[]): number {
// ...
}
Interfaces
/**
* A DataStore provides a means for retrieving stored data.
*/
export interface DataStore {
/** The source ID of the data store. */
readonly sourceId: string;
/** A unique 'type' identifier for the data store. */
readonly type: string;
/**
* Queries features based on a query clause.
*
* @param whereClause The where clause to apply to the query.
* @param options Any additional options to pass to the concrete data store implementation.
* @returns An observable of {https://geojson.org/ FeatureCollections}
*/
query(whereClause: string, options?: any): Observable<FeatureCollection>;
}
Classes
/**
* Data store configuration.
*
* @example new DataStoreConfig({ maxReturn: 500 });
*/
export class DataStoreConfig {
/**
* The maximum seconds to leave a connection open.
*/
timeout: number;
/**
* The maximum number of records to return in a query.
*/
maxReturn: number;
private isConnecting: boolean;
/**
* Creates a new instance with options.
*
* @param options Options to extend the class properties by.
*/
constructor(options: { maxReturn: number; timeout: number }) {
// ...
}
/**
* Converts the instance to a JSON string.
*
* @param format Whether to format the JSON response or not.
*/
toJson(format = true): string {
// ...
}
}
Components
/**
* Provides a simple searchbox UI with minimal interaction needed.
*
* @example
* <rizing-search-box expanded="true"></rizing-search-box>
*/
@Component({
selector: "rizing-search-box",
templateUrl: "./search-box.component.html",
styleUrls: ["./search-box.component.scss"],
})
export class SearchBoxComponent {
/**
* Flag to determine if the search box should be expanded or not.
*/
@Input() expanded: boolean;
private isFocused: boolean;
/**
* Creates a new search box instance.
*
* @param options Options to extend the class properties by.
*/
constructor(
/**
* Service that provides search capabilities.
*/
readonly searchService: SearchService,
readonly anchorService: AnchorService
) {
// ...
}
/**
* Converts the instance to a JSON string.
*
* @param format Whether to format the JSON response or not.
*/
toJson(format = true): string {
return generateJson(this, format);
}
}
// NOTE: This does not need documented because it is not exported.
function generateJson(value: any, format = true): string {}
// ...
}