본문 바로가기

개발/프로그래머스 데브코스

프로그래머스 데브코스 52일차 with. TS 웹 풀스택

📚요약

지난 시간에 이어 타입스크립트를 공부해 보겠습니다.

 

📖타입스크립트

📄데이터 타입

📑리터럴 타입

타입을 더 직관적으로 볼 수 있는 리터럴 타입이 있습니다. 해당 타입을 사용하게 되면 코드의 가독성이 높아지고, 값을 강제로 정해주었기 때문에 잘못된 값이 들어오는 것을 예방할 수 있습니다.

// 리터럴
// 문자열 리터럴
let gender:'male' | 'female';
gender = 'male'; // o
gender = 'man'; // error male과 female만 사용 가능

// 숫자 리터럴
let num: 10 | 100 | 1000;
num = 10; // o
num = 5; // error 10,100,1000만 사용 가능

// boolean 리터럴
let flag: true;
flag = true; // o
flag = false; // error true만 사용 가능

// 객체 리터럴
let obj: { pro1 : string, pro2 : number, pro3 : string };
obj = {
  pro1 : 'obj', // o
  pro2 : true, // error 숫자만 가능
  // error pro3 속성이 무조건 있어야 함
}

 

📑타입 별칭

 

type 키워드를 이용하면 타입에 별칭을 부여할 수 있습니다.

type Gender = 'male' | 'female';

let gender:Gender;
gender = 'male'; // o
gender = 'woman'; // error male과 female만 사용 가능

 

📑any 타입

 

any 타입은 타입에 제한을 두지 않는다는 말입니다. 자바스크립트처럼 타입에 신경 쓰지 않고 사용하겠다는 말과 같습니다. 하지만 타입스크립트에서는 최대한 데이터의 타입을 알려주어야 하기 때문에 any를 남용하는 것은 좋지 않고, 외부 모듈을 사용하는데 타입을 알 수 없는 경우나 타입이 애매한 경우에만 사용하는 것을 권장합니다.

let anyEl : any;
anyEl = 5; // o
anyEl = o; // o
anyEl = 'any'; // o

 

📑유니온(공용체) 타입

유니온 타입은 제한된 타입을 동시에 지정하고 싶을 때 사용합니다. 리터럴 타입이 값에 대한 범위를 지정했다면, 유니온 타입은 타입에 대한 범위를 지정합니다.

let numStr : number | string;
numStr = 5; // o
numStr = '5'; // o
numStr = true; // error 숫자와 문자열만 사용 가능
🍯tip! 타입은 작은 범위(하나의 타입)에 큰 범위(둘 이상의 타입)의 값을 할당할 수 없다.

 

📑타입 가드

타입 가드는 타입을 사용할 때 다른 타입을 사용해 발생할 수 있는 에러를 미리 예방하는 코드들을 의미합니다. 쉽게 말해 미리 타입을 확인하고 사용하다는 말입니다.

  • typeof 키워드 : 값의 타입 확인
  • Array.isArray() : 배열 확인
  • instanceof  : 클래스 타입 확인
  • in : 객체에서 같은 타입인데 다른 속성명을 가진 경우 사용
  • .속성명 : 객체에서 같은 속성명이지만 다른 값을 가진 경우

📑배열 타입

let numArr : number[] = [1,2,3,4];
let strArr : string[] = ['a','b','c'];

// 배열에 유니온 타입 사용
let mixArr : (number | string)[] = [1,'a',2,'b'];

// 읽기 전용 배열
let conArr : ReadonlyArray<number> = [1,2,3];
conArr[0] = 4; // error 수정할 수 없다.

 

📑튜플 타입

배열과 비슷하지만 타입의 순서가 정해져 있고 길이가 고정적인 배열이라고 생각하면 됩니다.

let tup : [number,string, boolean] = [1,,'a',true];

 

🍯tip! 선택적 매개변수(?를 사용한 경우)는 default와 마찬가지로 마지막에 와야 한다.
function func(a:string, b?:number, c:string) {}
// error 선택적 매개변수인 b가 마지막에 와야 한다
// 또는
// c 또한 선택적 매개변수이어야 한다​


또한 선택적 매개변수를 사용하게 되면 타입이 지정된 타입과 undefined가 추가되기 때문에 그에 유의해야 한다.

 

📄클래스

클래스를 만들고 생성자 함수와 접근 지정자까지 적용해 보겠습니다.

type Gender = "male" | "female";

class Human {
  private _name: string;
  private _age: number;
  private _gender: Gender | undefined;

  constructor(name: string, age: number, gender?: Gender) {
    this._name = name;
    this._age = age;
    this._gender = gender;
  }

  getName = (): void => {
    console.log(this._name);
  };
}

let james = new Human("james", 10, "male"); // 객체 생성
james.getName(); // james

james._age = 11; // error 접근지정자를 private으로 설정한 필드에 접근할 수 없다

 

생성자 함수를 사용할 때 필드도 생성해 주고 초기화까지 하려면 코드가 너무 길어져 타입스크립트에서 간단한 방법도 만들어두었습니다. 생성자 함수의 매개변수에 접근 지정자를 추가하면 됩니다.

type Gender = "male" | "female";

class Human {
  constructor(
    private _name: string,
    private _age: number,
    private _gender?: Gender
  ) {}
}

let james = new Human("james", 10, "male");

 

또한 캡슐화를 위해서 접근지정자인 private을 사용했지만 다른 접근 방식을 제공하기 위해서 get과 set 키워드를 이용할 수 있습니다. 키워드를 이용해서 만든 경우 할당하는 방식과 기존 .을 통해 접근하는 방식을 사용할 수 있습니다.

type Gender = "male" | "female";

class Human {
  constructor(
    private _name: string,
    private _age: number,
    private _gender?: Gender
  ) {}

  getName = (): void => {
    console.log(this._name);
  };
  
  set name(name: string) {
    this.name = name;
  }

  get age(): number {
    return this._age;
  }

  set age(v: number) {
    this._age = v;
  }
}

let james = new Human("james", 10, "male");
james.getName(); // james

james.age = 11;
console.log(james.age); // 11
🍯tip! private 지정자를 사용할 경우 필드명을 _로 시작하면 구분하기 편하다.

 

다음 시간에 계속...

 

출처 & 참고

이창현 강사님의 강의

타입 추론/타입 호환/ 타입 단언/ 타입 가드, inpa, 2024.06.17