타입스크립트 강의 내용 정리 (1)
■ 옵셔널 파라미터
해당 파라미터는 포함해도되고 포함하지 않아도 된다.
function log(a: string, b?: string) {}
■ Type Aliases vs. Interface
1. 타입 별칭은 새로운 타입 값을 하나 생성하는 것이 아니라
이미 정의한 타입에 대해 나중에 쉽게 참고할 수 있게 이름을 부여하는 것과 같다.
2. 가장 큰 차이점은 확장 가능 여부. 타입은 확장이 불가능하다.
따라서 가능한 한 type보다는 interface로 선언해서 사용하는 것을 추천.
■ 타입 가드
특정 타입으로 타입의 범위를 좁혀나가는(필터링하는) 과정
function logMessage(value: string | number) {
if (typeof value === 'number') {
// 이 if문 안에서는 value의 타입이 number로 추론된다.
value.toLocaleString();
}
if (typeof value === 'string') {
// 여기서는 value가 string으로 추론된다.
value.toLocaleUpperCase();
}
}
■ union type
interface Developer {
name: string;
skill: string;
}
interface Person {
name: string;
age: number;
}
function askSomeone(someone: Developer | Person) {
someone.skill // X
someone.name // O
}
someone은 Developer도 될 수 있고 Person도 될 수 있다.
타입스크립트의 관점에서는 someone이 둘 중 어떤 타입이 될지 모르기때문에
Developer의 skill이라던가 Person의 age를 타입 검증도 없이 바로 쓰게 되면
그 코드는 type safe 하지 않은, 즉 에러가 충분히 발생할 수 있는 코드라고 판단한다.
만약 someone.skill이나 someone.age를 쓰고 싶다면 타입 가드를 통해 둘 중 하나의 타입으로 제한해줘야 함.
■ union type과 intersection type의 호출 시 차이점
// union type
function askSomeone(someone: Developer | Person) {
// ...
}
askSomeone({ name: '개발자', skill: '웹 개발' });
askSomeone({ name: '사람', age: 100 });
// intersection type
function askSomeone(someone: Developer & Person) {
// ...
}
askSomeone({ name: '개발자', skill: '웹 개발', age: 100 });
union 타입인 someone은 말 그대로 Developer 아니면 Person 이므로 인자로 둘 중 하나가 들어가면 된다.
반면, intersection 타입인 someone은 Developer 이면서 Person 이어야하므로,
둘의 속성을 모두 가지는 객체를 인자로 집어넣어야한다.
■ 숫자형 enum
enum Shoes {
Nike, // 0
Adidas // 1
}
const myShoes = Shoes.Nike;
console.log(myShoes); // 0
// enum에 별도의 값을 지정하지 않으면 숫자형 enum으로 취급
enum Shoes {
Nike = 10, // 10
Adidas, // 11
NewBalance // 12
}
// 처음 지정한 숫자로부터 1씩 증가하는 형태
■ 문자형 enum
enum Shoes {
Nike = '나이키',
Adidas = '아디다스'
}
const myShoes = Shoes.Nike;
console.log(myShoes); // '나이키'
■ enum 사용 예시
// enum 사용 전
function askQuestion(answer: string) {
if (answer === 'yes') {
console.log('정답입니다');
}
if (answer === 'no') {
console.log('오답입니다');
}
}
askQuestion('예스');
askQuestion('y');
askQuestion('Yes');
// enum 사용 후
// 예외 처리의 케이스를 많이 줄일 수 있다.
enum Answer {
Yes = 'Y',
No = 'N'
}
function askQuestion(answer: Answer) {
if (answer === Answer.Yes) {
console.log('정답입니다');
}
if (answer === Answer.No) {
console.log('오답입니다');
}
}
askQuestion(Answer.Yes); // O
askQuestion('Yes'); // X
// enum으로 정의했으므로, enum에서 제공하는 데이터만 넣을 수 있다.
■ 몰랐던 Interface 사용 예시
// 함수의 스펙(구조)에 인터페이스를 활용
interface SumFunction {
(a: number, b: number): number;
}
const sum:SumFunction = function(a: number, b: number): number {
return a + b;
}
// 인덱싱 방식을 정의하는 인터페이스
interface StringArray {
[index: number]: string;
}
const arr: StringArray = ['a', 'b', 'c'];
arr[0]; // 'a'
// 딕셔너리 패턴
interface StringRegexDictionary {
[key: string]: RegExp;
}
const obj: StringRegexDictionary = {
cssFile: /\.css$/,
jsFile: /\.js$/,
}
obj.cssFile = 'a'; // X. RegExp 타입이 들어가야 함.