[프로그래머스] 프론트엔드 기초: React + TypeScript(7)

Lina Hongbi Ko·2024년 10월 29일
0

Programmers_BootCamp

목록 보기
44/76
post-thumbnail

2024년 10월 29일

✏️ 객체 리터럴

  • 특정 값만을 나타내는 타입
  • 리터럴 타입은 해당 값의 집합 중에 하나로 타입을 제한함
  • 리터럴 타입이란 문자 그대로 값 자체를 타입으로 지정하는 것임
// app.ts

// 열거형 : 사용자 정의 타입
enum GenderType {
  Male = 'male',
  Female = 'female'
}

interface Student {
  stdId : number;
	stdName : string;
	age? : number;
	gender? : 'male' | 'female'; // male과 female로 제한시킴
	// 이 두개의 값이 아닌 다른 문자열이 들어오면 오류남
	course? : string;
	completed : boolean;

  setName(name : string) : void; // 1) 일반함수
	// setName? : (name : string) => void // 2) 화살표함수
	// getName? : () => string
}
  • 리터럴 타입은 특정 값을 나타내는 타입으로 해당 값이 정확하게 일치해야 한다. 타입스크립트에서 사용되는 리터럴 타입에는 다양한 종류가 있다.

    • 문자열 리터럴 타입
      • let status : ‘sucess’ | ‘error’
        status = ‘success’ // 유효
        status = ‘pending’ // 에러: ‘pending’은 허용되지 않음
    • 숫자 리터럴 타입
      • let speed : 50 | 100 | 200;
        speed = 100; // 유효
        speed = 150; // 에러: 150은 허용되지 않음
    • 불리언 리터럴 타입
      • let isTrue : true;
        isTrue = true; // 유효
        isTrue = false; // 에러: false는 허용되지 않음
    • 객체 리터럴 타입 (가장 많이 사용)
      • let person : { name : ‘John’, age : 30};
        person = { name : ‘John’, age : 30}; // 유효
        person = { name: ‘Alice’, age : 25}; // 에러: 값이 일치해야함
    • 타입 별칭
      • type CardinalDirection = ‘North’ | ‘East’ | ‘South’ | ‘West’;
        let direction : CardinalDirection;
        direction = ‘North’; // 유효
        direction = ‘Northeast’; // 에러: ‘Northeast’는 허용되지 않음
  • 리터럴 타입을 사용하면 좋은 점

    • 코드의 가독성이 높아짐
    • 잘못된 값이 들어오는 것을 방지할 수 있음(엄격함)
  • 객체 타입 지정

// app.ts

const user = {
	name : 'john',
	age: 25
}

// 위 객체의 타입을 명확하게 지정하면
const user : {name : string, age : number}= {
	name : 'john',
	age: '25' // error
}

*리터럴타입 참고사이트 : https://growing-jiwoo.tistory.com/59

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

  • any 타입

    • 타입 체크를 하지 않는다. 어떠한 타입이 오더라도 ok

      // app.ts
      
      let anyVal : any = 100;
      anyVal = '200'; // error 발생하지 않음
    • 타입스크립트는 타입에 관한 정보가 더 많을수록 더 좋다.

    • 타입 정보는 개발자의 의도를 명확하게 전달 할 수 있다.

    • 효과적인 코드의 유지보수가 가능하다.

    • any 타입을 이루벌 사용하지는 말자.

    • 타입을 지정할 수 없는 제한적인 경우에만 any 타입을 사용하라.

    • 유니온 타입 (공용체)

      • 제한된 타입을 동시에 지정하고 싶을 때가 있다.

      • 제한된 타입들을 파이프라인으로 구분하여 동시에 지정.

      • let anyVale : number | string;
        -> | 기호를 사이에 두고 동시에 타입을 지정할 수 있다.
        -> anyVal 변수는 number이나 string 타입 중 아무 타입의 값이 올 수 있음

        // app.ts
        
        let anyVal : number | string = 100;
        anyVal = true; // error
        
        // union 타입
        let numStr : number | string = 100;
        
        function convertToString(val : number | string) : string {
          return String(val);
        }
        
        function convertToNumber(val : number | string) : number {
          return Number(val);
        }
        
        console.log(convertToString(numStr)); // 문자열 100
        console.log(convertToNumber(numStr)); // 숫자 100
    • 그런데, 유니온 타입을 계속 위의 코드 처럼 반복하는 게 아니라, 이 유니온 타입 자체를 재정의 해서 타입으로 사용할 수 있다

  • 타입 별칭 (type alias)

    • 반복되는 코드를 재사용

    • 기존에 있는 타입을 재정의해서 새로운 타입을 만듦

      • type strOrNum = number | string;

        // app.ts
        
        type strOrNum = number | string;
        
        let numStr : strOrNum = 100;
        
        function convertToString(val : strOrNum) : string {
          return String(val);
        }
        
        function convertToNumber(val : strOrNum) : number {
          return Number(val);
        }
        
        console.log(convertToString(numStr)); // 문자열 100
        console.log(convertToNumber(numStr)); // 숫자 100
  • 타입가드

    • typeof 사용

      • typeof 연산자를 이용하여 타입 검증을 수행한다.

      • 유니온 타입을 사용할 때는 typeof를 사용해서 처리하는게 좋음

        // app.ts
        
        type strOrNum = number | string;
        
        let numStr : strOrNum = 100;
        let item : number;
        
        function convertToString(val : strOrNum) : string {
          item = numStr; // error
          // 작은 범위 -> 큰 범위는 문제 없지만
          // 큰 범위 -> 작은 범위는 문제가 생김
          // 위의 코드는 큰 범위가 작은 범위가 되려고 하니 문제 생김
          // numStr에 숫자 또는 문자열이 들어올 수 있음
          // 따라서 item에 문자열이 들어 올 수 있으므로 에러가 생김
        
          // 따라서 타입가드를 사용해줘야함
          // 타입을 검사함
          // typeof operator을 사용해서 해결
          // 해당변수의 타입을 리턴
          if(typeof val == 'string') {
              item = 0;
          } else {
              item = val;
          }
        
          return String(val);
        }
        
        function convertToNumber(val : strOrNum) : number {
          return Number(val);
        }

✏️ Array & Tuple

  • Array는 길이가 가변적이며 동일한 타입의 요소로 구성
  • Tuple은 길이가 고정적이며 각 요소의 타입이 정해져 있음
// app.ts

// Array 타입
let numbers : number[] = [1, 2, 3, 4, 5];
let fruits : string[] = ['apple', 'banana', 'orange'];

for(let i = 0; i < numbers.length; i++) {
  console.log(numbers[i]); // 1 2 3 4 5
}

for(let i = 0; i < fruits.length; i++) {
  console.log(numbers[i]); // apple banana orange
}


// 배열의 유니온 타입
let mixedArray : (number | string)[]= [1, 'two', 3, 'four'];

for(let i = 0; i < mixedArray.length; i++) {
  console.log(mixedArray[i]); // 1 two 3 four
}

// 타입 추론
let infer = [1, 2, 3];

for(let i = 0; i < infer.length; i++) {
  console.log(infer[i]); // 1 2 3
}

// readOnly
let readOnlyArray : ReadonlyArray<number> = [1, 2, 3];

// Tuple 타입 (타입스크립트에서만 사용) : 타입의 순서가 정해져 있음
let greeting : [number, string, boolean] = [1, 'hello', true];

for(let i = 0; i < greeting.length; i++) {
  console.log(greeting[i]); // 1, hello, true
}

// spread 연산자
let firstArray = [1, 2, 3];
let secondArray = [4, 5, 6];

let newArray = [...firstArray, ...secondArray];
console.log(newArray); // [1, 2, 3, 4, 5, 6]

✏️ 클래스와 객체

  • 클래스 : 객체의 뼈대(붕어빵틀)
    • 객체는 클래스의 실체(붕어빵)
// oop.ts

// 일반적인 직원 정보
let empName : string;
let age : number;
let empJob : string;

function printEmp(empName : string, age : number, empJob : string) : void {
  console.log(`${empName}의 나이는 ${age}이고, 직업은 ${empJob}입니다.`)
}

printEmp('lee', 22, 'developer');
// lee의 나이는 22이고, 직업은 developer입니다.
  • 위의 정보들을 묶어주기 위해 클래스를 사용해보자
// oop.ts

// 멤버 변수 == 속성 == 프로퍼티
// 멤버 함수 == 메소드

class Employee {
  empName : string;
  age : number;
  empJob : string;

  printEmp = () : void => {
    console.log(`${this.empName}의 나이는 ${this.age}이고, 직업은 ${this.empJob}입니다.`)
  }
}

let employee1 = new Employee();
employee1.empName = 'kim';
employee1.age = 20;
employee1.empJob = '개발자';

employee1.printEmp();

✏️ 생성자

  • 클래스에서 초기값들을 생성자를 이용해서 할당한다
// oop.ts

class Employee {
	empName : string;
  age : number;
  empJob : string;

  constructor(empName : string, age? : number, empJob? : string) {
		// 옵셔널 선택자를 사용하려면 뒤까지 다 써줘야함
		this.empName = empName;
		this.age = age;
		this.empJob = empJob;
  }

  printEmp = () : void => {
    console.log(`${this.empName}의 나이는 ${this.age}이고, 직업은 ${this.empJob}입니다.`)
  }
}

let employee1 = new Employee('kim', 20, 'devloper');
employee1.empName = 'lee'
employee1.printEmp(); // lee의 나이는 20이고, 직업은 devloper입니다.

✏️ 접근지정자

  • 객체지향의 캡슐화 철학을 위해 접근지정자를 사용
  • 데이터 접근 제한을 위한 사용 → private
// oop.ts

class Employee {
	private _empName : string;
  private _age : number;
  private _empJob : string;

  constructor(empName : string, age? : number, empJob? : string) {
		// 옵셔널 선택자를 사용하려면 뒤까지 다 써줘야함
		this._empName = empName;
		this._age = age;
		this._empJob = empJob;
  }

  printEmp = () : void => {
    console.log(`${this._empName}의 나이는 ${this._age}이고, 직업은 ${this._empJob}입니다.`)
  }
}

let employee1 = new Employee('kim', 20, 'devloper');
employee1.empName = 'lee' // error
employee1.printEmp();

✏️ getter & setter

  • 캡슐화한 변수들을 접근하기 위한 메소드를 사용한다.
// oop.ts

class Employee {
  constructor(
    private _empName : string,
    private _age : number, 
    private _empJob : string
  ) {

  }

  // get/set
  get empName() {
    return this._empName;
  }

  set empName(val : string) {
    this._empName = val;
  }

  printEmp = () : void => {
    console.log(`${this._empName}의 나이는 ${this._age}이고, 직업은 ${this._empJob}입니다.`)
  }
}

let employee1 = new Employee('kim', 20, 'devloper');
employee1.empName = 'lee';
employee1.printEmp(); // lee의 나이는 20이고, 직업은 devloper입니다.
profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글