자바스크립트에서는 여러가지 자료형을 제공합니다. (자바스크립트 자료형) 타입스크립트도 자바스크립트가 제공하는 자료형을 당연히 제공하는데요.
하지만 타입스크립트는 자바스크립트가 제공하는 것보다 더 많은 타입(Tuple, Enum, ... etc.)이 있고, 심지어 개발자가 사용자 정의 타입을 만들 수도 있습니다.
먼저 타입스크립트가 제공하는 기본 타입을 알아봅시다.
let i:number = 10
let f:number = 1.3
let n:number = -5
let s:string = 'str'
let t:string = `str`
let s2:string = "str"
true
와 false
만 가집니다.자바스크립트에서는 0
, 1
, null
, undefined
등이 truthy
혹은 falsy
, 즉 참 같은 값, 거짓 같은 값으로 판단되어 if 조건문 속에서 사용되는 경우가 있습니다.
하지만 타입스크립트에서는 true
와 false
외에는 boolean 타입으로 인정하지 않습니다.
let t:boolean = true
let f:boolean = false
타입스크립트에서 객체를 다루는 방식을 살펴보겠습니다.
객체를 하나 만들고, 새로운 속성을 지정해보겠습니다.
const obj = {
name: 'Yeony',
age: 24,
}
console.log(obj.name) // 컴파일 에러 Property 'name' does not exist on type 'object'.
obj.hobby = 'traveling' // 컴파일 에러: Property 'hobby' does not exist on type 'object'.
name
과 hobby
모두 속성이 해당 객체에 없다고 표시됩니다.
타입스크립트에서는 위 객체의 데이터 타입을 아래와 같이 추론합니다.
const obj: {
name: string;
age: number;
}
이 내용이 obj에 저장된 데이터 타입이라고 생각하는 것이죠. 이 추론에 따르면 name
프로퍼티는 무조건 string
이여야 하고, age
또한 number
타입이어야 합니다.
obj
가 객체라고 명시해보겠습니다.
// 타입 const obj: object
const obj: object = {
name: 'Yeony',
age: 24,
}
console.log(obj.name) // 컴파일 에러
obj.hobby = 'traveling' // 컴파일 에러
타입스크립트는 이제 obj
가 객체 타입이라고 인식하지만, 컴파일은 여전히 되지 않습니다.
이 상황을 해결하기 위해 우리는 좀더 상세한 타입 지정을 할 수 있습니다.
const obj: {
name: string;
age: number;
} = {
name: 'Yeony',
age: 24,
}
console.log(obj.name)
obj.hobby = 'traveling' // 컴파일 에러
이제 name
은 접근이 가능합니다. 하지만 여전히 동적 할당은 컴파일 단계에서 에러가 발생합니다. hobby
라는 key가 정의되지 않았기 때문입니다.
동적 할당이 가능하게 하려면 프로퍼티 키가 무엇이 들어오더라도 가능하게끔 코드를 수정해야 합니다.
자바스크립트의 객체를 상기해봅시다. 객체는 key-value 쌍으로 이루어져 있고, key는 문자열입니다. value는 어떤 자료형이든 가능합니다.
따라서 동적 할당이 가능하게 하려면 아래와 같이 작성해야 합니다.
const obj: {
name: string;
age: number;
[key: string]: any;
} = {
name: 'Yeony',
age: 24,
}
console.log(obj.name)
obj.hobby = 'traveling'
타입스크립트에서는 특정한 타입으로 이루어진 배열을 선언할 수 있습니다.
let favoriteFood: string[];
favoriteFood = ["pizza", "chicken"]
favoriteFood = ["gulasch", 1] // 컴파일 에러: Type 'number' is not assignable to type 'string'.
string[]
이나 number[]
같이 작성합니다.
// only number
let nums:number[] = [1, 2, 3]
let strs:string[] = ['a', 'b', 'c']
let bools:boolean[] = [true, false, true]
자바스크립트에서 작동하는 배열처럼 작성할 경우에는 any[]
로 지정해줍니다.
let anys:any[] = [1, 'a', true]
단일한 타입이나 타입을 무시하는(any) 배열이 아닌, 특정한 여러 타입만 들어오는 배열을 정의하고 싶을 때엔 이렇게 작성합니다.
let selects:(number | string | boolean)[] = [1, 'c', false];
이러한 형태를 union 타입 이라고 합니다.
튜플은 이러한 형태로 작성됩니다.
const role = [2, 'author']
// 타입
// role: (string | number)[]
다만 위 코드에서는 role
이 일반적인 배열로 인식됩니다. 타입스크립트는 개발자가 2가지 요소만 입력할 것이란 걸 아직 모르기 때문입니다. 그러면 더 이상 튜플이 아닙니다.
튜플이라는 것을 명시하려면 이렇게 작성합니다.
const role: [number, string] = [2, 'author']
role[1] = 3 // 컴파일 에러 Type 'number' is not assignable to type 'string'.
role[3] = 11 // 컴파일 에러 Tuple type '[number, string]' of length '2' has no element at index '3'.
특정한 규칙(순서)로 정보를 담을 때 유용합니다.
사용자 정보를 (사용자 인덱스 | 이메일 | 비밀번호) 구조로 저장한다고 가정했을 때, 뒤죽박죽되면 당연히 곤란하겠죠.
튜플의 길이를 벗어나게 할당하려고 하거나 명시된 순서에 맞지 않는 자료형의 값을 할당하면 에러가 표시되니 관리하기 수월합니다.
튜플은 길이가 고정되어 있다고 했지만, 명시적인 할당에만 반응합니다.
const role: [number, string] = [2, 'author']
// role[3] = 11 // 컴파일 에러
role.push('메롱')
console.log(role) // [2, "author", "메롱"]
자바스크립트 Array의 내장 메소드인 push()
메소드에는 대응할 수 없다는 단점이 있습니다.
사용자 권한을 작성할 때 0은 ADMIN, 1은 USER, 2는 AUTHOR 라고 정했다고 가정해봅시다.
이 규칙을 절대 잊어버리지 않는다면 큰 문제가 발생하진 않겠지만, if 검사를 할 때 개발 도중 잊어버릴 가능성도 있습니다.
혹은 'ADMIN', 'VALID_USER' 등의 문자열로도 작성할 수 있겠죠. 하지만 if(role === 'VALID_USER')
이런 식으로 작성하면 과연 효율이 좋을까요?
개발자가 읽기 쉽고(문자열), 백그라손쉽게 코딩하기 위해 Enum을 사용합니다.
enum Role {
ADMIN, USER, AUTHOR
};
const user:{
name: string;
role: Role
} = {
name: 'Yeony',
role: Role.USER
}
Enum은 기본적으로 0부터 시작해 할당됩니다.
enum Role {
ADMIN, USER, AUTHOR
};
// --------------------
// enum의 타입
Role.ADMIN = 0
Role.USER = 1
Role.AUTHOR = 2
만약 0이 아닌 다른 수로 시작하고 싶다면 아래와 같이 명시합니다.
enum Role {
ADMIN = 3, USER, AUTHOR
};
// --------------------
// enum의 타입
Role.ADMIN = 3
Role.USER = 4
Role.AUTHOR = 5
enum Role {
ADMIN = 3, USER = 100, AUTHOR
};
// --------------------
// enum의 타입
Role.ADMIN = 3
Role.USER = 100
Role.AUTHOR = 101
숫자가 기본이지만 문자열도 할당할 수 있습니다.
enum Role {
ADMIN = 'ADMIN', USER = 100, AUTHOR
};
// --------------------
// enum의 타입
Role.ADMIN = 'ADMIN'
Role.USER = 100
Role.AUTHOR = 101
하지만 문자열로 할당했을 경우, USER = 100
같이 숫자로 초기화를 하지 않으면 에러가 발생합니다.
enum Role {
ADMIN = 'ADMIN', USER, AUTHOR // 컴파일 에러 : Enum member must have initializer
}
위에서 객체 타입을 보며 잠깐 보았듯, any
는 아주 유연합니다. 사실상 타입을 신경쓰지 않겠다는 말이기도 하죠.
따라서 가능한 한 새로운 코드를 작성할 때에는 any 타입을 지정하지 않는 것이 좋습니다. 타입스크립트가 제공하는 모든 장점을 any가 상쇄시키기 때문이죠.
이미 있는 프로젝트에 타입스크립트를 점진적으로 적용할 때 유용합니다.
undefined
만 할당할 수 있습니다.자바스크립트에서 함수는 반환 값이 있을 수도 있고, 없을 수도 있습니다. 함수에 return 값
코드가 없는 경우에 자바스크립트는 undefined
를 반환합니다.
타입스크립트에서는 반환 값이 없다는 것을 명시적으로 보여주기 위해 void
를 사용합니다.
let ud: void = undefined
function sayHello(name:string): void {
console.log(`Hi, ${name}!`)
}
// 항상 오류
function alwaysError(msg:string): never {
throw new Error(msg);
}
// 무한루프
function infiniteLoop(): never {
while(true) {
//...
}
}
변수의 타입을 never
로 지정한 경우에는 never
만 할당할 수 있습니다. any
타입도 불가능합니다.
let neverType:never;
neverType = 100; // 컴파일 에러
// 함수의 반환 타입이 never
neverType = (function():never { throw new Error('Error') })();