Coding style is mostly enforced by a pre-commit hook that runs eslint
. This hook is installed whenever running yarn install
on any of the application directory. If for some reason the pre-commit hook didn't get installed, you can manually install it by running yarn install
at the root of the repository.
Because the TypeScript compiler generates .js
files, be sure to add these new .js
files to .eslintignore
and .gitignore
.
To do this,
- If the TypeScript compiler has already generated a
.js
file for the new.ts
file, delete it. - Run
yarn run updateIgnored
in the root directory of the project (oryarn run postinstall
)
Even if you are modifying a file that was originally in JavaScript you should ideally convert it first to TypeScript before modifying it.
If this is a large file however please ask first if it needs to be converted. Some very old and large JS files are tricky to convert properly due to poorly defined types, so in some cases it's better to leave that for another day (or another PR).
camelCase.ts
: Files that export multiple things.- Example:
checkForUpdates.ts
- Example:
PascalCase.ts
: Only if the file contains a single class, which is the default export.types.ts
orfooTypes.ts
: Shared type definitions- Example :
types.ts
- Example :
If you create a file that exports a single function called processData()
, the file should be named processData.ts
. When importing, it should be imported as processData
, too. Basically, be consistent with naming, even though JS allows things to be named differently.
BAD:
// ProcessDATA.ts
export default const processData = () => {
// ...
};
// foo.ts
import doDataProcessing from './ProcessDATA';
doDataProcessing();
...
Good:
// processData.ts
export default const processData = () => {
// ...
};
// foo.ts
import processData from './processData';
processData();
...
BAD:
// Bad! Don't use in new code!
const GRAVITY_ACCEL = 9.8;
Good:
const gravityAccel = 9.8;
VSCode: In vscode
, be sure to check whether new files are created with tab
or space
indentation! Spaces can be converted to tabs using the command palette.
Use ===
instead of ==
.
Although the TypeScript compiler will give error messages if two different types are compared with ==
(e.g. number == boolean
), its compiler error messages in this case can be misleading.
BAD:
// Bad!
let foo, bar;
const doThings = () => {
// do things unrelated to foo, bar
};
// Do things involving foo and bar
foo = Math.random();
bar = foo + Math.random() / 100;
foo += Math.sin(bar + Math.tan(foo));
...
Good:
...
const doThings = () => {
// do things unrelated to foo, bar
};
// Do things involving foo and bar
let foo = Math.random();
let bar = foo + Math.random() / 100;
foo += Math.sin(bar + Math.tan(foo));
...
Don't allow this to lead to duplicate code, however. If constants are used multiple times, it's okay to declare them at the top of a file or in a separate, imported file.
Doing this avoids having to deal with the this
keyword. Not having it makes it easier to refactor class components into React Hooks, because any use of this
(used in classes) will be correctly detected as invalid by TypeScript.
BAD:
// Bad!
function foo() {
...
}
Good:
const foo = () => {
...
};
As much as possible, avoid default parameters in function definitions and optional fields in interface definitions. When all parameters are required, it is much easier to refactor the code because the compiler will automatically catch any missing parameters.
New code should use React Hooks and function
components, rather than objects that extend Component
.
Bad:
// Don't do this in new code!
class Example extends React.Component {
constructor(props: { text: string }) {
super(props);
}
render() {
return (
<div>${text}</div>
);
}
}
Good:
const Example = (props: { text: string }) => {
return (
<div>${text}</div>
);
};
Use react custom hooks to simplify long code
If eslint
gives an error about useFoo
being called outside of a component, be sure the custom hook is titled appropriately.
We aren't using these guides, but they may still be helpful!
- TypeScript Deep Dive — Style Guide
- Google TypeScript style guide
- See also
ts.dev
's style guide, which is based on the Google style guide.
- See also
- Javascript standardstyle
- Possibly useful for adding to
.eslintrc.js
: listseslint
configuration flags for each of their suggestions
- Possibly useful for adding to
- Forum Post: Troubleshooting FAQ and collecting topic for contributing to Joplin codebase
- Forum Post: How to style your code
- GSoC: GSoC 2022 pull request guidelines
- GitHub:
.eslintrc.js