프로그래머스 풀스택 44
posted on 29 Oct 2024 under category programmers in series programmers
프론트엔드 기초: React + TypeScript(7)
💫 객체 리터럴
리터럴 타입 (enum보다 간단)
리터럴 값은 특정 값을 나타내는 타입.
문자열 리터럴 타입
let gender : 'male' | 'female';
이런 식으로 하면
male과 female 값 둘 중 하나만 들어올 수 있게 제한 가능
기존의 gender? : string;
을 하면 다른 값이 들어올 수 있었음
숫자 리터럴 타입
let speed : 50|100|200;
speed=100;
: 유효
speed=150;
: 에러. 150은 허용 X
불리언 리터럴 타입
let isTrue : true;
isTrue = true;
: 유효
isTrue = false;
: 에러. false 허용 X
객체 리터럴 타입(가장 많이 사용)
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’ 허용 X
리터럴 타입 사용 시 장점
let anyVal : any = 100;
anyVal = true;
any 타입
💫 유니온
유니온 타입
let anyVal : number | string;
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));
console.log(convertToNumber(numStr));
💫 타입 별칭(Type Alias)
type strOrNum = number | string;
type strOrNum = number | string;
let numStr : strOrNum = '100';
function convertToString(val : strOrNum):string {
return String(val); //무조건 문자열 변환 출력
}
function convertToNumber(val : strOrNum):number {
return Number(val); // 무조건 숫자 변환 출력
}
💫 타입가드
type strOrNum = number | string;
let numStr : strOrNum = '100';
let item : number;
function convertToString(val : strOrNum):string {
item = numStr; //
return String(val); //무조건 문자열 변환 출력
}
item = numStr;
은 item 변수에 대입되는 numStr의 타입이 유니온타입이라 오류가 발생함(string이 들어갈 수도 있으니까)타입가드 적용
type strOrNum = number | string;
let numStr : strOrNum = '100';
let item : number;
function convertToString(val : strOrNum):string {
if(typeof val ==='string') {
item = 0;
}else{
item = val;
}
return String(val); //무조건 문자열 변환 출력
}
요약
💫 Array와 Tuple
Array와 Tuple의 차이점
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]);
}
for(let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
let mixedArray : (number | string)[] = [1, 'two', 3, 'four'];
for(let i = 0; i < mixedArray.length; i++) {
console.log(mixedArray[i]);
};
let infer = [1, 2, 3];
for(let i = 0; i < infer.length; i++) {
console.log(infer[i]);
};
let readOnlyArray : ReadonlyArray<number> = [1, 2, 3];
let greeting : [number, string, boolean] = [1, 'hello', true];
for(let i = 0; i < greeting.length; i++) {
console.log(greeting[i]);
};
let firstArray = [1, 2, 3];
let secondArray = [4, 5, 6];
let combineArray = [...firstArray, ...secondArray]; //Spread 연산자(...) => 무장해제
for(let i = 0; i < combineArray.length; i++) {
console.log(combineArray[i]);
};
💫 클래스와 객체 만들기
타입스크립트 기반의 객체 지향 프로그래밍(Object-Oriented Programming, OOP)
멤버변수 == 속성 == 프로퍼티
멤버함수 == 메소드
// 클래스 생성
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 = 25;
employee1.empJob = '개발자';
// 메소드 호출
employee1.printEmp();
💫 생성자
객체 지향 프로그래밍에는 생성자가 내장됨
프로퍼티의 초기값을 생성자를 이용해 설정할 수 있음
모든 클래스는 생성자라는 메소드를 가질 수 있음
컴파일 기반의 언어에서는 생성자를 따로 만들어야 함
생성자 메소드 규칙
클래스와 같은 이름을 갖고 있으면 됨
하지만 타입스크립트는 constructor()
이런식으로 생성자가 고정되어 사용함
// 클래스 생성
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', 30, '소프트웨어개발자');
// 메소드 호출
employee1.printEmp();
constructor(empName : string, age? : number, empJob? : string)
💫 접근지정자
프로퍼티를 생성자를 이용해 객체를 초기화했음
프로퍼티의 값은 객체를 통해서 다른 값으로 변경할 수 있음
접근을 제한 👉 객체 지향의 “캡슐화”
public, private, protected 을 사용해 접근을 통제할 수 있음
public : default로 설정
class Employee {
private _empName : string; // private를 사용하면 클래스 밖에서는 접근 불가능
private _age : number;
private _empJob : string;
// ...생략
}
이를 해결하기 위해 getter와 setter를 사용함!
private 변수를 쓸경우 변수명 앞에 _을 붙여줌. 👉 _변수명
💫 getter와 setter
타입스크립트 말고도 일반적으로 함수에서 어떤 데이터를 다루는 함수는 get/set함수라고 얘기를 함
클래스 내의 메소드에서 사용을 하게 됨
get/set 함수의 존재 이유 : 데이터들을 직접 접근하지 않고 ,특정 메소드를 통해서 출입을 해야하므로
인터페이스를 만들어줄 때 데이터를 다루는 메소드같은 경우 get/set를 한 쌍으로 만들어주는 게 관례 같은 것
👉 이걸 타입스크립트에서는 getter와 setter로 사용하는 것일 뿐임
get empName(){
return this._empName;
}
set empName(val : string){
this._empName = val;
}
// 클래스 생성
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', 30, '소프트웨어개발자');
employee1.empName = 'lee'; // 접근지정자 적용이 필요함 -> get/set 설정
// 메소드 호출
employee1.printEmp();
Y 일을 통해 명확히 알게 되었거나 이해한 부분(한 일)에 대해 정리 :
객체 리터럴, 유니온, 타입 별칭, 생성자/접근지정자, 등등
W 배운 점과 시사점 :
객체 리터럴 타입(가장 많이 사용)
let person : { name: 'John', age: 30 };
person : { name: 'John', age: 30 };
: 유효
person : { name: 'Alice', age: 25 };
: 에러. 값이 일치해야 함.
T 응용하여 배운 것을 어디에 어떻게 적용할지:
클래스와 객체를 생성하고 코드를 고도화할 수 있게 됨