development

타입스크립트(typescript) 클린코드

여름싼타 2022. 12. 1. 19:03
반응형

타입스크립트 클린코드 정리

 

1. 불필요한 컨텍스트 삭제

클래스/유형/객체명으로 선언한 값을 컨텍스트로 반복하지 않는다. 굳이 반복할 필요가 없다.

type Car = {
  carMake: string;
  carModel: string;
  carColor: string;
}

function print(car: Car): void {
  console.log(`${car.carMake} ${car.carModel} (${car.carColor})`);
}

아래처럼 컨텍스트를 빼고 사용

type Car = {
  make: string;
  model: string;
  color: string;
}

function print(car: Car): void {
  console.log(`${car.make} ${car.model} (${car.color})`);
}

 

2. enum 사용

Enums는 코드의 의도를 문서화하는 데 도움이 된다.

const GENRE = {
  ROMANTIC: 'romantic',
  DRAMA: 'drama',
  COMEDY: 'comedy',
  DOCUMENTARY: 'documentary',
}

projector.configureFilm(GENRE.COMEDY);

class Projector {
  // declaration of Projector
  configureFilm(genre) {
    switch (genre) {
      case GENRE.ROMANTIC:
        // some logic to be executed 
    }
  }
}

아래처럼 고칠수 있다.

enum GENRE {
  ROMANTIC,
  DRAMA,
  COMEDY,
  DOCUMENTARY,
}

projector.configureFilm(GENRE.COMEDY);

class Projector {
  // declaration of Projector
  configureFilm(genre) {
    switch (genre) {
      case GENRE.ROMANTIC:
        // some logic to be executed 
    }
  }

 

3. 함수명은 기능을 나타낼 수 있도록 작성

function addToDate(date: Date, month: number): Date {
  // ...
}
const date = new Date();
addToDate(date, 1);

아래처럼 변경

function addMonthToDate(date: Date, month: number): Date {
  // ...
}

const date = new Date();
addMonthToDate(date, 1);

 

4. 함수형 프로그래밍을 활용하자

const contributions = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

let totalOutput = 0;

for (let i = 0; i < contributions.length; i++) {
  totalOutput += contributions[i].linesOfCode;
}

아래처럼 함수형으로 하면 더 좋다.

const contributions = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

const totalOutput = contributions
  .reduce((totalLines, output) => totalLines + output.linesOfCode, 0);


5. 부정적인 조건을 말고 긍정적인 조건을 사용

우리의 뇌는 부정조건보다 긍정 조건을 더 쉽게 이해한다고 한다.

function isEmailNotUsed(email: string): boolean {
  // ...
}

if (isEmailNotUsed(email)) {
  // ...
}

아래처럼 바꾸자

function isEmailUsed(email: string): boolean {
  // ...
}

if (!isEmailUsed(email)) {
  // ...
}

 

6. 바뀌지 않는 값은 불변하도록 설정

interface Config {
  host: string;
  port: string;
  db: string;
}

이런 값들은 바뀌지 않으니까 아래처럼 변경

interface Config {
  readonly host: string;
  readonly port: string;
  readonly db: string;
}

 

7. 테스트는 단일 책임 원칙 따르기

테스트는 단일 책임 원칙을 따라야 한다. 유닛 테스트마다 assert를 하나만 수행한다.

import { assert } from 'chai';

describe('AwesomeDate', () => {
  it('handles date boundaries', () => {
    let date: AwesomeDate;

    date = new AwesomeDate('1/1/2015');
    assert.equal('1/31/2015', date.addDays(30));

    date = new AwesomeDate('2/1/2016');
    assert.equal('2/29/2016', date.addDays(28));

    date = new AwesomeDate('2/1/2015');
    assert.equal('3/1/2015', date.addDays(28));
  });
});

이렇게 하나의 테스트에 여러개를 수행하지 말고 아래처럼 변경하자

import { assert } from 'chai';

describe('AwesomeDate', () => {
  it('handles 30-day months', () => {
    const date = new AwesomeDate('1/1/2015');
    assert.equal('1/31/2015', date.addDays(30));
  });

  it('handles leap year', () => {
    const date = new AwesomeDate('2/1/2016');
    assert.equal('2/29/2016', date.addDays(28));
  });

  it('handles non-leap year', () => {
    const date = new AwesomeDate('2/1/2015');
    assert.equal('3/1/2015', date.addDays(28));
  });
});

 

반응형