-
Notifications
You must be signed in to change notification settings - Fork 5
Development Practices
Modularise functions. If your file or function is getting too big, break it up <3
Keep branches short and focused. If refactor work is needed, finish that off in a another branch first. Makes code reviews less painful, get things merged in faster.
Follow branch name convention:
<module>/#<ticket-number>/description
e.g. frontend/#69/adding-cool-box
No spaces - use dashes. No capitalisation.
Note we have components and view as separate folders. Components are for reusable components, view is for describing the actual page layout.
> api
> component
> types
> view
> Header
> Timetable
- Timetable.tsx
- App.tsx
- App.test.tsx
> utils
- colorMapper.ts
- colorMapper.test.ts
- index.ts
import React, { FunctionComponent } from 'react'
interface MyComponentProps {
name: string
meow(): void
meowName(name: string): string
} // always have object as react prop. Type using interfaces
const MyComponent: FunctionComponent<MyComponentProps> = ({ name, meow, meowName }) => { // destructure here
return <div />
}
export { MyComponent } // named exports and named imports
The view (jsx part) shouldn't contain logic. Keep them separate for readbility.
GOOD:
const MyComponent = () => {
const handleClick = () => {
console.log()
}
return <button onClick={handleClick} />
}
BAD:
const MyComponent = () => {
return <button onClick={() => console.log()} />
}
Use interface to define objects. Use types for everything else. Interfaces has extra functionality such as (extends) which helps with objects.
interfaces
GOOD:
interface TimePeriod {
start: Date
end: Date
}
BAD:
type TimePeriod = {
start: Date
end: Date
}
// types are good for more complex typescript
// type unions, type intersections, conditional, generic types
type ClassData = NormalClassData | SpecialClassData
It's okay to not explicitly type variables/objects if it is obvious what type they are. If it's not obviously clear, then you should be typing them explicitly:
const cat = (): string | number => {...}
const dog: string | number = cat()
GOOD:
const foo = (): bar => {...}
BAD:
function foo() {...}
This is to enforce that the arguments you pass into a function have the exact same names. This is to prevent accidentally mis-ordering your arguments.
GOOD:
const foo = ({arg1, arg2, arg3}: {arg1: string, arg2: string, arg3: boolean}): string => {...}
or if you want it to be more readable
interface fooParams {
arg1: string,
arg2: string,
arg3: boolean
}
const foo = ({arg1, arg2, arg3}: fooParams): string => {...}
BAD:
const foo = (arg1: string, arg2: string, arg3: boolean): string => {...}