Post

데브코스 TIL - Day 49

24년 1월 30일 강의를 들은 내용을 기록한 글입니다.

타입스크립트

📘객체리터럴

  • 해당 값의 집합 중에 하나로 타입을 제한하는 것
  • 허용되는 타입이 정해져있기 때문에 코드 가독성이 좋음
  • 잘못된 값이 들어오는 것을 방지할 수 있음 (엄격함)

■ 문자열 리터럴

1
2
3
let status: "success" | "error";
status = "success";
status = "pending"; // Error!

■ 숫자 리터럴

1
2
3
let speed: 50 | 100 | 200;
speed = 100;
speed = 150; // Error!

■ 불리언 리터럴

1
2
3
let isTrue: true;
isTrue = true;
isTrue = false; // Error!

■ 객체 리터럴

1
2
3
let person: { name: "김말순"; age: 30 };
person = { name: "김말순"; age: 30 };
person = { name: "김말수"; age: 25 }; // Error!

■ 타입 별칭

1
2
3
4
type CardinalDirection = "North" | "East" | "South" | "West";
let direction: CardinalDirection;
direction = "North";
direction = "Northeast"; // Error!

■ 예제

1
2
3
4
const user: { name: string; age: number } = {
  name: "김말숙",
  age: 25
};

유니온, 타입별칭, 타입가드

📘any

  • 어떠한 타입도 모두 받음 (오류가 발생하지 않음)
  • 타입을 지정할 수 없는 제한적인 경우에만 사용할 것
1
2
3
4
let variable: any;
variable = "hello";
variable = 42;
variable = true;

📘유니온 (Union Types)

  • 여러 타입 중 하나가 될 수 있는 타입
  • |를 사용하여 여러 타입을 결합
1
2
3
4
let variable: string | number;
variable = "hello";
variable = 42;
variable = true; // Error!

■ 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
let numStr: string | number = 100;

function convertToString(param: string | number): string {
  if (typeof param === "string") return param;
  return param.toString();
}
function convertToNumber(param: string | number): number {
  if (typeof param === "number") return param;
  return Number(param);
}

console.log(convertToString(numStr)); // "100"
console.log(convertToNumber(numStr)); // 100

📘타입별칭 (Type Aliases)

  • 타입의 이름을 지정하는 방법
  • type키워드를 사용하여 선언

■ 문법

1
2
3
4
type 타입이름 = {
  속성1: 타입;
  속성2: 타입;
};

■ 예시

  • 타입별칭으로 타입 선언하고 사용하기
1
2
3
4
5
6
type Animal = {
  name: string;
  animalType: string;
};
const choco: Animal = { name: "초코", animalType: "dog" };
const bella: Animal = { name: "벨라", animalType: "cat" };
  • 유니온에서 사용했던 코드 타입별칭으로 바꿔보기
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type strOrnum = string | number;
let numStr: strOrnum = 100;

function convertToString(param: strOrnum): string {
  if (typeof param === "string") return param;
  return param.toString();
}
function convertToNumber(param: strOrnum): number {
  if (typeof param === "number") return param;
  return Number(param);
}

console.log(convertToString(numStr)); // "100"
console.log(convertToNumber(numStr)); // 100

📘타입가드 (Type Guards)

  • 런타임에서 변수의 타입을 확인하고, 타입스크립트 컴파일러에게 해당 타입 정보를 제공
  • 코드 검증
  • typeof, instanceof 또는 사용자 정의 함수를 사용해서 타입가드를 만듬

■ 예시 1

  • bodyEle가 null일 수도 있다는 오류가 발생,
  • 이 때 bodyEle의 타입을 지정하면 오류가 사라짐
1
2
3
const bodyEle = document.querySelector("body");
bodyEle.innerText = "Hello World~";
// Error! 'bodyEle' is possibly 'null'.(18047)
  • 타입 가드를 사용하여 bodyEle의 타입을 지정
  • bodyEle가 있을 때만 “Hello World~”를 삽입하도록 설정
1
2
3
4
const bodyEle = document.querySelector("body");
if (bodyEle) {
  bodyEle.innerText = "Hello World~";
}

■ 예시 2

  • 여러개의 타입을 가지는 인자가 들어오면 타입 가드를 사용해서 코드 검증을 수행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type strOrnum = string | number;
let numStr: strOrnum = 100;

function convertToString(param: strOrnum): string {
  if (typeof param === "string") return param;
  return param.toString();
}
function convertToNumber(param: strOrnum): number {
  if (typeof param === "number") return param;
  return Number(param);
}

console.log(convertToString(numStr)); // "100"
console.log(convertToNumber(numStr)); // 100

array와 tuple

📘array

  • 배열의 타입을 지정하는 방법
1
2
const numbers: number[] = [1, 2, 3, 4, 5];
const alphabets: string[] = ["a", "b", "c", "d"];
  • 배열의 유니온 타입 지정하는 방법
1
const strOrNum: (number | string)[] = [1, "two", 3, "four", 5];
  • 타입스크립트 추론 이용하기
1
2
const numbers = [1, 2, 3, 4, 5];
// const numbers: number[]
  • 읽기 전용 타입 지정하기
1
2
const readOnlyArr: ReadonlyArray<number> = [1, 2, 3, 4, 5];
// const readOnlyArr: readonly number[]

📘tuple

  • 길이가 고정적
  • 타입의 순서가 정해져있을 때 사용
  • 자바스크립트에는 없고 타입스크립트에만 있는
1
const greeting: [number, string, boolean] = [1, "hello", true];

타입스크립트와 객체지향 프로그래밍

  • 연관된 변수와 함수들을 한 덩어리로 묶어 구조화하여 표현
  • 클래스: 설계도, 생산틀
  • 객체: 클래스의 실체

📘실습

  • 데이터가 많으면 관리하기가 힘들기 때문에
  • 클래스를 이용해서 관리
1
2
3
4
5
function printEmp(name: string, age: number, job: string): void {
  console.log(`이름: ${name}, 나이: ${age}, 업무: ${job}`);
}

printEmp("김말숙", 25, "인사"); // "이름: 김말숙, 나이: 25, 업무: 인사"

■ 클래스 만들기

1
2
3
4
5
6
7
8
9
class Employee {
  name: string = "";
  age: number = 0;
  job: string = "";

  printEmp(): void {
    console.log(`이름: ${this.name}, 나이: ${this.age}, 업무: ${this.job}`);
  }
}

■ 객체 만들기

1
2
3
4
5
6
const employee = new Employee();
employee.name = "김말숙";
employee.age = 30;
employee.job = "인사";

employee.printEmp(); // "이름: 김말숙, 나이: 25, 업무: 인사"

📘생성자 이용해서 객체 생성하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Employee {
  name: string;
  age: number;
  job: string;

  constructor(name: string, age: number, job: string) {
    this.name = name;
    this.age = age;
    this.job = job;
  }

  printEmp(): void {
    console.log(`이름: ${this.name}, 나이: ${this.age}, 업무: ${this.job}`);
  }
}

const employee1 = new Employee("김말이", 50, "청소");
employee1.printEmp(); // "이름: 김말이, 나이: 50, 업무: 청소"

■ 선택적 매개변수를 이용하기

  • 선택적 매개변수로 설정하면, 선택적 매개변수 이후의 매개변수들도 옵셔널해짐
  • 생성자에서 선택적 매개변수를 이용할 때는 기본값을 제공해줘야 함
    • 제공하지 않는다면 undefined가 할당되기 때문에 오류가 발생함
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Employee {
  name: string;
  age: number;
  job: string;

  constructor(name: string, age: number = 0, job: string = "") {
    this.name = name;
    this.age = age;
    this.job = job;
  }

  printEmp(): void {
    console.log(`이름: ${this.name}, 나이: ${this.age}, 업무: ${this.job}`);
  }
}

const employee1 = new Employee("김말이");
employee1.printEmp(); // "이름: 김말이, 나이: 0, 업무: "

📘접근지정자를 이용해서 데이터 보호하기

  • public
  • protected
  • private
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Employee {
  private _name: string;
  private _age: number;
  public job: string;

  constructor(name: string, age: number = 0, job: string = "") {
    this._name = name;
    this._age = age;
    this.job = job;
  }

  printEmp(): void {
    console.log(`이름: ${this._name}, 나이: ${this._age}, 업무: ${this.job}`);
  }
}
1
2
3
4
5
6
7
8
9
const employee1 = new Employee("김말이");
employee1.printEmp(); // "이름: 김말이, 나이: 0, 업무: "

employee1.job = "개발자";
employee1.printEmp(); // "이름: 김말이, 나이: 0, 업무: 개발자"

employee1._name = "김마리";
// Error!
// Property '_name' is private and only accessible within class 'Employee'.(2341)

📘getter, setter로 데이터에 접근하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Employee {
  private _name: string;
  private _age: number;
  private _job: string;

  constructor(name: string, age: number = 0, job: string = "") {
    this._name = name;
    this._age = age;
    this._job = job;
  }

  // get으로 name의 값을 가져오기(직접 접근하지 않음)
  get name() {
    return this._name;
  }

  // set으로 name의 값 변경하기
  set name(str: string) {
    this._name = str;
  }

  printEmp(): void {
    console.log(`이름: ${this._name}, 나이: ${this._age}, 업무: ${this._job}`);
  }
}
1
2
3
4
5
const employee1 = new Employee("김말이");
employee1.printEmp(); // "이름: 김말이, 나이: 0, 업무: "

employee1.name = "김마리";
employee1.printEmp(); // "이름: 김마리, 나이: 0, 업무: 개발자"

📘생성자 함수에서 타입을 선언하고 생성하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Employee {
  constructor(
    private _name: string,
    private _age: number = 0,
    public job: string = ""
  ) {}

  // get으로 name의 값을 가져오기(직접 접근하지 않음)
  get name() {
    return this._name;
  }

  // set으로 name의 값 변경하기
  set name(str: string) {
    this._name = str;
  }

  printEmp(): void {
    console.log(`이름: ${this._name}, 나이: ${this._age}, 업무: ${this.job}`);
  }
}

스프레드 연산자 (Spread 연산자)

  • ...키워드를 사용해서 배열이나 객체의 요소를 펼칠 때 사용
1
2
3
4
5
const firstArray = [1, 2, 3];
const secondArray = [4, 5, 6];
const newArray = [...firstArray, ...secondArray];

console.log(newArray); // [1, 2, 3, 4, 5, 6]
1
2
3
4
5
const firstObj = { a: 1, b: 2, c: 3 };
const secondObj = { d: 4, e: 5, f: 6 };
const newObj = { ...firstObj, ...secondObj };

console.log(newObj); // {"a": 1, "b": 2,"c": 3, "d": 4,"e": 5,"f": 6 }
This post is licensed under CC BY 4.0 by the author.