Awesome
TypeScript
These guidelines are adapted from the TypeScript core's contributor coding guidelines.
<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->Table of Contents
- Names
- Exports
- Components
- Types
null
andundefined
- General Assumptions
- Flags
- Comments
- Strings
- When to use
any
- Diagnostic Messages
- General Constructs
- Style
Names
- Use PascalCase for type names.
- Do not use "I" as a prefix for interface names.
- Use PascalCase for enum values.
- Use camelCase for function names.
- Use camelCase for property names and local variables.
- Do not use "_" as a prefix for private properties.
- Use whole words in names when possible.
- Use
isXXXing
orhasXXXXed
for variables representing states of things (e.g.isLoading
,hasCompletedOnboarding
). - Give folders/files/components/functions unique names.
Exports
- Only use named exports. The only exceptions are a tool requires default exports (e.g
React.lazy()
, Gatsby and Next.jspages
,typography.js
)
Components
- 1 file per logical component (e.g. parser, scanner, emitter, checker).
- If not kept in a separate folder, files with ".generated.*" suffix are auto-generated, do not hand-edit them.
- Tests should be kept in the same directory with ".test.*" suffix
- Filename should match the component name. Interfaces for React components should be called
<ComponentName>Props
and<ComponentName>State
. The only exception is when writing a render prop. In this situation, you, the author, should call the interface for your component's props<ComponentName>Config
and then the render prop interface<ComponentName>Props
so it is easy for everyone else to use.
Types
- Do not export types/functions unless you need to share it across multiple components.
- Do not introduce new types/values to the global namespace.
- Shared types should be defined in 'types.ts'.
- Within a file, type definitions should come first (after the imports).
null
and undefined
- Use undefined. Do not use
null
. EVER. If null is used (like in legacy Redux code), it should be kept isolated from other code with selectors.
General Assumptions
- Consider objects like Nodes, Symbols, etc. as immutable outside the component that created them. Do not change them.
- Consider arrays as immutable by default after creation.
Flags
- More than 2 related Boolean properties on a type should be turned into a flag.
Comments
- Use JSDoc style comments for functions, interfaces, enums, and classes.
- Document crazy stuff. Always add
@see <url>
and the current date when referencing external resources, blog posts, tweets, snippets, gists, issues etc. - Make note conditions upon which hacks and smelly code can be removed.
Strings
- Use single quotes for strings. Double quotes around JSX string props.
- All strings visible to the user need to be localized (make an entry in diagnosticMessages.json).
When to use any
- If something takes you longer than 10 minutes to type or you feel the need to read through TS Advanced Types docs, you should take a step back and ask for help, or use
unknown
. - Custom typings of 3rd-party modules should be added to a
.d.ts
file in atypings
directory. Document the date and version of the module you are typing at the top of the file. - Consider rewriting tiny modules in typescript if types are too hard to think through.
- Use
unknown
Diagnostic Messages
- Use a period at the end of a sentence.
- Use indefinite articles for indefinite entities.
- Definite entities should be named (this is for a variable name, type name, etc..).
- When stating a rule, the subject should be in the singular (e.g. "An external module cannot..." instead of "External modules cannot...").
- Use present tense.
- Use active voice.
General Constructs
For a variety of reasons, we avoid certain constructs, and use some of our own. Among them:
- Prefer
for..in
loops over.reduce
if it makes the code clearer or if you think you may need to do async work since you canawait
inside of it.
Style
- Use prettier and tslint/eslint.
- Use arrow functions over anonymous function expressions.
- Only surround arrow function parameters when necessary. <br />For example,
(x) => x + x
is 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. Statements on the same line are allowed to omit braces.
- Open curly braces always go on the same line as whatever necessitates them.
- Parenthesized constructs should have no surrounding whitespace. <br />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 <br />(i.e. use
var x = 1; var y = 2;
overvar x = 1, y = 2;
). - Use 2 spaces per indentation.
MIT LICENSE