Variables
1. 변수 이름은 구체적으로
Bad
// 변수
const AHCageId = 1
// 함수
const isBiggerThan = (a: number, b: number) => {
return a > b
}
Good
// 변수
const AdmissionHotelCageId = 1
// 함수
const isBiggerThan = (target: number, compareTarget: number) => {
return a > b
}
const getInitAData = () => {}
const generateInitBData = () => {}
const makeInitCData = () => {}
Good
const getInitAData = () => {}
const getInitBData = () => {}
const getInitCData = () => {}
// or
const generateInitAData = () => {}
const generateInitBData = () => {}
const generateInitCData = () => {}
// or
const makeInitAData = () => {}
const makeInitBData = () => {}
const makeInitCData = () => {}
Bad
setTimeout(someFunc, 86400000)
// and
.my_className {
position: relative;
left: 270px;
}
Good
const MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000
setTimeout(someFunc, MILLISECONDS_IN_A_DAY)
// and
.my_className {
position: relative;
left: calc(300px - 20px - 10px);
}
// padding, margin 등 계산한 값
Bad
const userNameMap = new Map<number, string>()
for (const data of userNameMap){
const id = data[0]
const name = data[1]
}
Good
const userNameMap = new Map<number, string>()
for (const [id, name] of userNameMap){
// ...
}
type Props = {
onClose?: () => void
pet?: GQLGetPet
}
export const PacsAddModal = (props: Props) => { ... }
Good
type Props = {
onClose?: () => void
pet?: GQLGetPet
}
export const PacsAddModal = ({ onClose, pet }: Props) => { ... }
type User = {
userId: number
userName: string
}
Good
type User = {
id: number
name: string
}
const showPrettyName = (name?: string) => {
return <div>{name ?? '2름'}</div>
}
Good
const showPrettyName =(name?: string = '2름') => {
return <div>{name}</div>
}
export function isSafeNumberWithConstraints(
value: number,
options?: {
minValue?: number
maxValue?: number
},
) {
// limit max
if (options?.maxValue && value > options.maxValue) return false
// limit min
if (options?.minValue && value < options.minValue) return false
return true
}
Good
export function isSafeNumberWithConstraints(
value: number,
options?: {
minValue?: number
maxValue?: number
},
) {
// limit max
if (options?.maxValue !== undefined && value > options.maxValue) return false
// limit min
if (options?.minValue !== undefined && value < options.minValue) return false
return true
}
type MyVar = {
id: number
status: number
}
const myVar = {
id: 1
status: 2
}
// ...
if (myVar.status === 1){
// ...
} else if(myVar.status === 2){
// ...
}
Good
enum EMyVarStatus {
A = 1,
B = 2,
C = 3
}
type MyVar = {
id: number
status: EMyVarStatus
}
const myVar = {
id: 1
status: EMyVarStatus.B
}
// ...
// 1
const a = new Map<MyEnum, string>([
[MyEnum.A, () => {}],
[MyEnum.B, () => {}]
])
// 2
switch (myVar.status){
case EMyVarStatus.A:
// ...
case EMyVarStatus.B:
// ...
default:
// ...
}
Function
함수
1. 매개변수 3개 이상은 object로 (+destructuring)
Bad
const sumOfLengthOfRectangle
= (width: number, height: number, depth: number) => {
return width + height + depth
}
Good
type RectangleSide = {
width: number
height: number
depth: number
}
const sumOfLengthOfRectangle
= ({width, height, depth}: RectangleSide) => {
return width + height + depth
}
const emailClients = (clients: Client[]) => {
clients.forEach((client) => {
const clientRecord = database.lookup(client)
if (clientRecord.isActive()) {
email(client)
}
});
}
// or
const getChildrenAndGetSumOfAge = () => {
const children = database.get('children')
return sumOf(children.map((child) => child.age))
}
Good
const emailClients = (clients: Client[]) => {
clients.filter(isActiveClient).forEach(email)
}
function isActiveClient(client: Client) {
const clientRecord = database.lookup(client)
return clientRecord.isActive()
}
// or
const getTotalAgeOfChildren = () => {
return sumOf(getChildrenAges())
}
const getChildrenAges = () => {
return database.get('children').map((child) => child.age)
}
코드 중복 제거하기
설명 귀찮음
함수 인자에 _(underscore) 붙이기
Bad
const someFunc = (child: Child, age: number) => {
// ...
}
// or
const childrenAges = myChildren.map((child) => {
return child.age
})
Good
const someFunc = (_child: Child, _age: number) => {
// ...
}
// or
const childrenAges = myChildren.map((_child) => {
return _child.age
})
⇒ 항상은 아니다.
Bad
const someFunc = ({_child, _age}: {_child: Child, _age: number}) => {
// ...
}
// or
const someFunc = ({_child: child, _age: age}
: {_child: Child, _age: number}) => {
// ...
}
Good
const someFunc = ({child, age}: {child: Child, age: number}) => {
// ...
}
const createFile = (name: string, temp: boolean) => {
if (temp) {
fs.create(`./temp/${name}`)
} else {
fs.create(name)
}
}
Good
const createTempFile = (name: string) => {
createFile(`./temp/${name}`)
}
const createFile = (name: string) => {
fs.create(name)
}
⇒ 하지만 이벤트 자체가 명확하지 않으면, 플래그 구분이 어딘가에는 결국 들어간다.
(이벤트 자체가 명확한 경우)
Bad
const handleButtonClick = (_myVar?: number) => () => {
if(_myVar !== undefined){
console.log(_myVar)
}else{
console.log('no!')
}
}
// ...
<button
onClick={handleButtonClick(5)}
>
버튼1
</buttn>
<button
onClick={handleButtonClick()}
>
버튼2
</buttn>
Good
const handleNumberButtonClick = (_myVar: number) => () => {
console.log(_myVar)
}
const handleButtonClick = () => {
console.log('no!')
}
// ...
<button
onClick={handleNumberButtonClick(5)}
>
버튼1
</buttn>
<button
onClick={handleButtonClick}
>
버튼2
</buttn>
export const SomeComponent = ({someA, someB}: Props) => {
const [count, setCount] = useState<number>(0)
const processSomething = () => {
console.log(count, someA)
}
const handleButtonClick = () => {
processSomething()
}
return (
...
)
}
Good
export const SomeComponent = ({someA, someB}: Props) => {
const [count, setCount] = useState<number>(0)
const processSomething = (_count: number, _someA: number) => {
console.log(_count, _someA)
}
const handleButtonClick = () => {
processSomething(count, someA)
}
return (
...
)
}
⇒ React 이벤트 핸들러에는 굳이..?
React에서 완벽한 순수함수를 하려면?
export const SomeComponent = ({someA, someB}: Props) => {
const [count, setCount] = useState<number>(0)
const processSomething = (_count: number, _someA: number) => {
console.log(_count, _someA)
}
const handleButtonClick = (_count: number, _someA: number) => () => {
processSomething(_count, _someA)
}
// 어차피 props 써야함
return (
<button onClick={handleButtonClick(count, someA)}>{...}</button>
)
}
const addItemToCart = (cart: CartItem[], item: Item): void => {
cart.push({ item, date: Date.now() })
}
Good
const addItemToCart = (cart: CartItem[], item: Item): CartItem[] => {
return cart.concat({ item, date: Date.now() })
}
let order = 0
if (condition1){
order = 3
}else if(condition2){
order = 1
}
console.log(order)
Good
const getOrderByCondition = () => {
if (condition1){
return 3
} else if (condition2){
return 1
}
return 0
}
const order = getOrderByCondition()
console.log(order)
if (subscription.isTrial || account.balance > 0) {
// ...
}
Good
const canActivateService = (_subscription: Subscription, _account: Account) => {
return _subscription.isTrial || _account.balance > 0
}
if (canActivateService(subscription, account)) {
// ...
}
const isEmailNotUsed = (email: string): boolean => {
// ...
}
if (isEmailNotUsed(email)) {
// ...
}
Good
const isEmailUsed = (email): boolean => {
// ...
}
if (!isEmailUsed(node)) {
// ...
}
const length = myList.length
for (let i = 0; i < length; i++ ) { ... }
Good
for (let i = 0; i < myList.length; i++ ) { ... }