Skip to content

Coding Standard

Anthony Halim edited this page May 25, 2020 · 9 revisions

1. Class and Function Comments

Above each class definition, it is required to have comments on what is the class purpose within the application. The only class exempted from class comments are self-explanatory class (short class, ~<50 LoC). Additionally, state its requirements/dependencies (if any). Below is an example of class comment.

/**
 * This is an example of class comment.
 * The class fetches the assessment of students.
 */
class SampleClass extends React.Component<...> { ... };

Above each high-complexity function definition, it is required to have comments on what is the purpose of the function. The only functions exempted from function comments are self-explanatory functions (short function, ~<10 LoC). Additionally, state its requirements/dependencies (if any). Below is an example of function comment.

/**
 * This is an example of function comment. 
 * The function serves the purpose of: ...
 */
const sampleFunction = () => { ... };

Other than class and function comments, all other comments must use the single-line comments (\\). Good code should be self-explanatory and not need much comments to begin with. Hence, if you find yourself writing many comments, consider refactoring the code for clarity.

2. Class Template

2.1 Class Initialisation Template

We declare the attributes within a type State outside the class, in which will be used as part of the React.Component.

type State = {
   a: ... ;
   b: ... ;
};

class Example extends React.Component<..., State> {
  constructor() {
    this.state = {
      a = ...
      b = ...
    };
  }
}

2.2. Order of Class Methods

Within the class, the methods should be ordered as: 1. Constructor, 2. Handlers, 3. Helpers, 4. componentDidMount (if applicable), and 5. render (if applicable)

class EgExample extends ... = () => {
  constructor()
  handlerEventA()
  ...
  handlerEventZ() 
  helperMethodA()
  ...
  helperMethodZ()
  componentDidMount()
  render()
}

3. Import Statements

Between import statements, the import statements must be ordered alphabetically based on its import path. Within a group import, the modules must be sorted alphabetically.

import {
  aaa,
  bbb,
  ccc,
  sss
} from ...; <-- Modules are ordered alphabetically within group imports

import zComponent from 'aaa/component'
import aComponent from 'zzz/component' <-- Alphabetical order based on import path

4. <``> Format

Prefer one line format:

const EgExample extends React.Component<DispatchProps, {}> = () => { 
 ...
}

Compared to:

const EgExample extends React.Component<
  DispatchProps, {}
> = () => { 
 ...
}

5. Interface vs Types

Unless absolutely needed, prefer Types to Interface.

type ComponentProps = DispatchProps & OwnProps & StateProps;
type DispatchProps = { ... };
type OwnProps = { ... };
type StateProps = { ... };

6. Do NOT Export Nameless Functions or Modules

Always export functions or modules under a unique name. We provide the following example:

const ExampleContainer = withRouter<IPropType>(
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(Example)
);

export default ExampleContainer;

Similarly when importing the module, do not rename the module as much as possible. We have seen the horror of programmer naming ability, and do not wish to perpetuate it. The following is an example of what should NOT been done:

import IWantToBeSpecialSoIRenameTheComponent from './ControlButton'

7. Usage of index.ts

We do NOT welcome usage of index.ts in this project. While it has its uses under conventional practice, it has inflicted more confusion than benefits under this project.

index.ts, under this project, will specifically refer to the root page.

8. DispatchProps, StateProps, OwnProps

The three props must be defined at its component file i.e. ...Component.tsx. Do not rename it to anything else. The combination of the three props, must be named as Props.

type WorkspaceProps = DispatchProps & StateProps & OwnProps;
type DispatchProps = { ... };
type StateProps = { ... };
type OwnProps = { ... };