-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Coding Guidelines
Rob Moran edited this page Aug 3, 2018
·
48 revisions
Use 4 spaces per indentation
- Use PascalCase for
typenames - Use PascalCase for
enumvalues - Use camelCase for
functionandmethodnames - Use camelCase for
propertynames andlocal variables - Use whole words in names when possible
- Use lower case, dash-separated file names (e.g.
document-provider.ts) - Name files after the main Type it exports
- Add architectural types to the file name separated by a dot. (e.g.
file-navigator.plugin.ts) - Do not use "_" as a prefix for private properties
- Do not export
typesorfunctionsunless you need to share it across multiple components, see as well - Do not introduce new
typesorvaluesto the global namespace
- Do not use I prefix for interfaces.
- Use Impl suffix for implementation of interfaces with the same name.
- See #624 for the discussion on this.
- Use JSDoc style comments for
functions,interfaces,enums, andclasses
- Use 'single quotes' for all strings which aren't template literals
Use undefined, do not use null.
- Use arrow functions
=>over anonymous function expressions - Only surround arrow function parameters when necessary. For example,
(x) => x + xis wrong but the following are correct:
x => x + x
(x,y) => x + y
<T>(x: T, y: T) => x === y- Always surround loop and conditional bodies with curly braces
- Open curly braces always go on the same line as whatever necessitates them
- Parenthesized constructs should have no surrounding whitespace. A single space follows commas, colons, and semicolons in those constructs. For example:
for (var i = 0, n = str.length; i < 10; i++) { }
if (x < 10) { }
function f(x: number, y: string): void { }- Use a single declaration per variable statement
(i.e. usevar x = 1; var y = 2;overvar x = 1, y = 2;). -
elsegoes on the line of the closing curly brace.
- 1. Use the property injection over the construction injection. Adding new dependencies via the construction injection is a breaking change.
-
2. Use
postConstructto initialize an object, for example to register event listeners.
@injectable()
export class MyComponent {
@inject(ApplicationShell)
protected readonly shell: ApplicationShell;
@postConstruct()
protected init(): void {
this.shell.activeChanged.connect(() => this.doSomething());
}
}-
3. Make sure to add
inSingletonScopefor singleton instances, otherwise a new instance will be created on each injection request.
// bad
bind(CommandContribution).to(LoggerFrontendContribution);
// good
bind(CommandContribution).to(LoggerFrontendContribution).inSingletonScope();- 4. Don't export functions, convert them into class methods. Functions cannot be overridden to change the behaviour or workaround a bug.
// bad
export function createWebSocket(url: string): WebSocket {
...
}
// good
@injectable()
export class WebSocketProvider {
protected createWebSocket(url: string): WebSocket {
...
}
}
@injectable()
export class MyWebSocketProvider extends WebSocketProvider {
protected createWebSocket(url: string): WebSocket {
// create a web socket with custom options
}
}- 4.1 Convenient functions which are based on the stable API can be exported in the corresponding namespace.
In this case clients:
- can customize behaviour via exchanging the API implementation
- have a choice to use convenient functions or an API directly
export namespace MonacoEditor {
// convenient function to get a Monaco editor based on the editor manager API
export function getCurrent(manager: EditorManager): MonacoEditor | undefined {
return get(manager.currentEditor);
}
...
}JSON types are not supposed to be implementable, but only instantiable. They cannot have functions to avoid serialization issues.
export interface CompositeTreeNode extends TreeNode {
children: ReadonlyArray<TreeNode>;
// bad - JSON types should not have functions
getFirstChild(): TreeNode | undefined;
}
// good - JSON types can have corresponding namespaces with functions
export namespace CompositeTreeNode {
export function getFirstChild(parent: CompositeTreeNode): TreeNode | undefined {
return parent.children[0];
}
...
}
// bad - JSON types should not be implemented
export class MyCompositeTreeNode implements CompositeTreeNode {
...
}
// good - JSON types can be extended
export interface MyCompositeTreeNode extends CompositeTreeNode {
...
}- 4.3 Auxiliary functions which are called from the customizable context can be exported in the corresponding namespace.
@injectable()
export class DirtyDiffModel {
// this method can be overridden, subclasses have an access to `DirtyDiffModel.documentContentLines`
protected handleDocumentChanged(document: TextEditorDocument): void {
this.currentContent = DirtyDiffModel.documentContentLines(document);
this.update();
}
}
export namespace DirtyDiffModel {
// the auxiliary function
export function documentContentLines(document: TextEditorDocument): ContentLines {
...
}
}- Use the
lower-case-with-dashesformat. - Prefix classes with
theiawhen used as global classes.
Project Management
- Roadmap
- Dev Meetings
- Technical Meetings
- Community Call
- Intellectual Property (IP) guide
- Registering CQs (Deprecated)
Documentation