우선 나는 타입 별칭과 무엇이 다른가 궁금했다. 큰 차이는 아래와 같다.
interface User {
name: string;
age: number;
}
let minseok: User;
interface fooFunction {
// 인자는 괄호를 이용해 표시
// 반환 타입도 함수 정의와 동일하게 뒤에 표시
(a: number, b: number): number;
}
interface stringArray {
//인덱싱 방식 자체를 정의
//숫자로 인덱싱 할 수 있는 것은 string만 가능하게 됨
[index: number]: string
}
interface stringRegexDictionary {
[key: string]: RegExp;
}
let obj: stringRegexDictionary = {
//아래 경우는 에러가 발생하게 됨
//key 값이 string인 경우에 정규표현식이 위치해야함
cssFile: "hello"
//아래 경우는 interface와 동일하므로
//에러가 발생하지 않음
jsFile: /\.js$/
}
//상속될 interface
interface Person{
name: string;
age: number;
}
//Person interface를 상속할 interface
//Person을 확장했으므로 name과 age는 모두 가지고 있음
interfae Developer extends Person{
skills: string[]
}
const minseok: Developer = {
name: "minseok",
age: 0,
skills: ["js", "java", "Dart"]
}
function logMessage(message: any): void {
console.log(message);
}
어떤 메시지를 출력해주는 함수를 위와 같이 정의하고자 합니다. message 인자로 string, number가 모두 들어올 수 있다고 생각해서 any라고 타입을 지정해주었습니다. 하지만 이런식으로 타입스크립트를 사용하면 자바스크립트를 사용하는 것과 차별점이 없습니다. 이런 상황을 위한 연산자를 이용한 타입 정의를 알아보겠습니다.
function logMessage(message: string | number): void {
console.log(message);
}
위와 같은 타입을 union type이라고 하며 string과 number 모두 전달할 수 있게 됩니다. 또한 이렇게 union type을 사용할 경우 타입스크립트의 장점을 아래와 같이 살릴 수 있게 됩니다.
function logMessage(message: string | number): void {
if(typeof message === "number") {
//message는 타입 number로 추론되는 상황
message.
}else {
//message가 타입 string으로 추론되는 상황
}
}
그런데 아래 예시를 보자. 유니온 타입이 포함하는 타입의 공통적인 부분만을 허용하는 것을 확인할 수 있다.
interface Developer {
name: string;
skills: string[];
}
interface Person {
name: string;
age: number;
}
function getSomeone(someone: Developer | Person) {
//에러 발생하지 않음
someone.name
//에러 발생
someone.age
someone.skills
}
인터섹션의 타입에 포함하는 모든 타입을 만족하는 타입을 의미하게 된다. 아래와 같은 경우의 foo는 어떤 타입도 만족할 수 없게 된다. string이면서 number이면서 boolean인 변수는 존재할 수 없으므로
let foo: string & number & boolean;
interface Developer {
name: string;
skills: string[];
}
interface Person {
name: string;
age: number;
}
function getSomeone(someone: Developer & Person) {
//Developer와 Person을 모두
//포함하게 되는 타입이므로
//에러 발생하지 않음
someone.name
someone.age
someone.skills
}