이 글은 타입스크립트 입문 - 기초부터 실전까지의 연산자를 이용한 타입 정의와 이넘, 클래스를 보고 정리한 글입니다.
logMessage라는 함수는 현재
value
라는 값에 string으로만 타입을 지정해주었기에 100이라는 숫자값이 들어오게 되면, 타입 에러가 발생한다. 이러한 경우 any를 사용하면 해결이 되지만, 이는 타입스크립트를 사용하는 메리트를 없앤다. 따라서 이러한 경우|
(유니온 타입)을 사용한다.
function logMessage(value: string | number) {
console.log(value);
}
logMessage('hello');
logMessage(100);
한 가지 타입 이상을 정의하고 싶다면 이
|
유니온 타입을 이용하면 정의할 수 있다.
// 변수에 유니온 설정하기
let numOrString: number | string;
const logMessage = (value: string | number) => {
if (typeof value === 'number') {
value.toLocaleString();
}
if (typeof value === 'string') {
value.toString();
}
throw new TypeError('value must be string or number');
};
logMessage('hello');
logMessage(100);
유니온 타입의 장점으로 타입가드(특정 타입으로 타입의 범위를 좁혀나가는 과정)를 통해 vscode가 변수의 타입을 알고, 사용할 수 있는 아래와 같이 보여준다.
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
const askSomeone = (someone: Developer | Person) => {
someone.name;
someone.skill; // 에러 감지
someone.age; // 에러 감지
};
인터페이스로 정의된
Developer
와Person
을 유니온 타입으로 사용 시,name
이라는 공통된 속성만 사용할 수 있게 vscode에서 보여준다. (보장된 속성에 한해서만 추천해줌)
위 사진은 nev라는 변수에 인터섹션 타입을 사용하여 string, number, boolean 타입을 정의하였을 시 나오는 never
라는 타입이 나온다. --> 당연히 string이면서 number, boolean이라는 값이 없기 때문에
const askSomeone2 = (someone: Developer & Person) => {
someone.name;
someone.skill;
someone.age;
};
아까
askSomeone
과 달리askSomeone2
에서는 인터섹션 타입을 사용하여Developer
와Person
을 타입으로 정의하여(Developer의 속성과 Person의 속성을 가진 하나의 타입이 됨) 타입가드의 필요 없이 각 인터페이스가 가지고 있는 모든 속성을 사용할 수 있다.
// 유니온 타입
const askSomeone = (someone: Developer | Person) => {
// someone.name;
// someone.skill;
// someone.age;
};
askSomeone({ name: '디벨로퍼', skill: '웹 개발' });
askSomeone({ name: '디벨로퍼', age: 100 });
// 인터섹션 타입
const askSomeone2 = (someone: Developer & Person) => {
someone.name;
someone.skill;
someone.age;
};
askSomeone2({ name: '디벨로퍼', skill: '웹 개발', age: 100 });
위 예제에서 확인할 수 있듯이, 유니온 타입으로 정의하게 되면 함수를 호출할때,
Developer
나Person
의 속성을 가지고 있는 인수만으로 호출하여도 에러가 발생하지 않는다. 그러나 인터섹션의 경우Developer
와Person
의 속성들을 모두 가지고 있는 인수를 전달하여 호출해야한다.
특정 값들의 집합을 의미하는 자료형
enum Shoes {
Nike,
Adidas,
}
let myShoes = Shoes.Nike;
console.log(myShoes); // 0
이넘 사용시 별도 값을 지정하지 않으면 숫자형 이넘이 된다는 사실을 확인할 수 있다.
enum Shoes {
Nike = '나이키',
Adidas = '아디다스',
}
let myShoes = Shoes.Nike;
console.log(myShoes); // '나이키'
문자형 이넘으로 사용하고 싶은 경우엔 위와 같이 직접 정의해서 사용한다.
const askQuestion = (answer: string) => {
if (answer === "YES") {
console.log('정답입니다.');
}
if (answer === "NO") {
console.log('오답입니다.');
}
}
askQuestion('y');
askQuestion('예');
askQuestion
이라는 함수가 있을 때 대답을 넘겨주는 인수로y, 예
와 같이 다양하게 줄 수 있는데, 이럴 때 Enum을 사용하면 예외 케이스 처리나 코드의 정확도를 높일 수 있다.
enum Answer {
YES = 'Y',
NO = 'N',
}
// 예제
const askQuestion = (answer: Answer) => {
if (answer === Answer.YES) {
console.log('정답입니다.');
}
if (answer === Answer.NO) {
console.log('오답입니다.');
}
};
askQuestion(Answer.YES);
askQuestion(Answer.NO);
ES6에서 소개된 문법
class Person {
// 클래스 로직
constructor(name, age) {
console.log('생성 되었습니다.');
this.name = name;
this.age = age;
}
}
const JM = new Person('정민', 25); // 생성 되었습니다.
console.log(JM);
클래스 예약어를 사용하여
constructor
와 함께 사용한다. 이를 통해 인스턴스를 생성할 수 있다.
프로토타입은 자바스크립트에서 상속을 구현하기 위한 메커니즘으로 위의 예시를 살펴보면 Person
이라는 객체를 JM
이라는 객체가 프로토타입으로 상속을 하고 있다.
이를 통해 JM이라는 객체는 Person이 가지고 있는 속성을 프로토타입 체인을 통해 상속받아 사용할 수 있게 된다.
프로토타입에 대해 더 자세하게 알고 싶다면 모던 자바스크립트 Deep Dive의 프로토타입을 읽어보는 것 또한 추천한다.
내가 정리한것: [모던 자바스크립트 Deep Dive] - 19~21장
let obj = { a: 10};
이러한 obj라는
object
가 있다고 가정하자. 브라우저에서 콘솔로obj.
을 찍으면 이 obj가 사용할 수 있는 메서드들을 볼 수 있다.
이는 obj의 프로토타입인 Object
가 가지고있는 메서드로 다음과 같이 확인할 수 있다.
마찬가지로 object
가 아닌 배열 또한 Array.prototype으로 배열전용 메서드들을 보여주는 것을 확인할 수 있다.
너무 많아서 잘라서 가져옴..
function Person(name, age) {
this.name = name;
this.age = age;
}
const capt = new Person('캡틴', 100);
클래스가 나오기 전에 생성자 함수를 정의하면 위와같이 정의할 수 있었다.
클래스가 나오게 된 이유는 자바와 같은 객체지향에 익숙한 개발자들이 자바스크립트를 사용하는데 편리하라고 만들었다고 한다.
클래스 문법으로 작성된 코드를 바벨에서 돌려보면 결국function
생성자 함수가 된다는 것을 확인할 수 있다.
class Person {
private name: string;
public age: number;
readonly log: string;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
타입스크립트에서 클래스를 사용하기 위해서는 사용하는 변수
name
,age
에 대한 타입 정의가 필요하다. 또한private
,public
,readonly
와 같은 키워드들을 사용할 수 있다.