const player : {
name:string,
age?:number // age를 optional한 값으로
} = {
name:"nico"
}
player
는 name:string
과 age:number
를 가진 object
✨ age
를 선택적 변수로 만들고 싶다면 ?
를 붙이면 된다.
// player 호버 시
const player : {
name:string;
age?:number | undefined;
}
age는 number 타입이거나, undefined!
if (player.age < 10) { // Err: Object is possibly 'undefined'
something...
}
타입스크립트는 player.age
가 undefined
일 수도 있다는 사실을 안다.
if (player.age && player.age < 10) {
something...
}
player.age
가 존재하는 지 확인하는 과정을 거친 후, if문 실행하도록 작성해야 한다.
const playerNico : {
name:string,
age?:number
} = {
name:"nico"
}
const playerLynn : {
name:string,
age?:number
} = {
name:"lynn"
age:12,
}
...
똑같은 타입을 반복해서 계속 적어줘야 한다.
⇒ 이 때 사용할 수 있는 것이 Alias 타입!
type Player = {
name:string,
age?:number
}
const nico : Player = {
name:"nico"
}
const lynn : Player = {
name:"lynn"
age:12,
}
...
Player
라는 타입을 정의하여 사용하면 코드를 반복하지 않아도 된다!
type Age = number;
type Player = {
name:string,
age?:Age
}
원한다면 age
의 타입만을 따로 정의할 수도 있다.
(물론 위 코드에서 이렇게 할 필요는 없음)
type Player = {
name:string,
age?:number
}
// arguments의 타입을 지정
function playerMaker(name:string){
return {
name // 인자로 들어온 name
}
}
const nico = playerMaker("nico")
nico.age = 12 // Err
현재 playerMaker
는 name
이라는 요소만 가지고 있는 object를 return하기 때문에 age를 추가할 수 없다.
type Player = {
name:string,
age?:number
}
// ✨ 함수의 return값에 Player라는 타입을 지정!!
function playerMaker(name:string) : Player {
return {
name
}
}
const nico = playerMaker("nico")
nico.age = 12
⇒ playerMaker
는 인자로 name:string
을 받고, Player
타입을 return하는 함수
이제 TypeScript는 nico
가 Player
타입임을 알기 때문에 age
값을 추가할 수 있게 된다.
const playerMaker = (name:string) : Player => ({name})
위처럼 작성 가능하다!
요소들을 '읽기 전용'으로 만들 수 있는 속성
type Player = {
readonly name:string,
age?:number
}
const playerMaker = (name:string) : Player => ({name})
const nico = playerMaker("nico")
nico.name = "las" // Err: cannot assign to 'name' because it is a read-only property
name
에 readonly
속성을 부여했기 때문에, name 값을 변경할 수 없게 된다!
const numbers: readonly number[] = [1, 2, 3, 4]
numbers.push(1) // Err: Property 'push' does not exist on type 'readonly number[]'
name.filter(...)
name.map(...)
readonly
속성이 부여된 타입에 push
는 할 수 없지만, map
이나 filter
는 가능하다.
⇒ map
, filter
는 원본 배열을 변경시키지 않으므로! (immutability, 불변성)
최소한의 길이를 갖고, 특정 위치에 특정 타입이 있는 배열을 생성
이름(string), 나이(number), 챔피언여부(boolean) 순으로 만들어진 배열을 만들어보자!
const player: [string, number, boolean] = ["nico", 1, true]
player[0] = 1 // Err: Type 'number' is not assignable to type 'string'
만약 player의 0번째 인덱스(string)을 number 값으로 변경하려 한다면, 에러가 발생하게 된다.
const player: readonly [string, number, boolean] = ["nico", 1, true]
물론, readonly
속성과 함께 사용할 수도 있다!
함께 사용할 경우 배열의 어떠한 값도 변경할 수 없게 된다.
let a : undefined = undefined
let b : null = null
JavaScript에도 존재하는 타입으로, undefined
은 undefined
, null
은 null
TypeScript로 빠져나오고 싶을 때 사용하는 타입
any
는 말그대로 아무 타입이나 될 수 있다.
✨ any
타입을 사용할 경우, TypeScript의 보호장치를 비활성화 시키므로 사용을 권장하지는 않는다.
const a = any[] = [1, 2, 3, 4]
const b = any = true
a + b
any
타입을 사용할 경우, 위처럼 number
로 이루어진 배열에 boolean
타입을 더하는 것을 허용하게 된다.
⇒ JavaScript로 작업하는 것과 동일해지는 것!
어떤 타입인 지 모를 때에 사용하는 타입
ex. API 통신 시, 응답의 타입을 모를 경우
let a : unknown;
let b = a + 1 // Err: Object is of type 'unknown'
unknown 타입을 사용할 경우, 어떤 작업을 하려면 이 변수의 타입을 먼저 확인해야 하는 방식으로 TypeScript의 보호를 받게 된다.
unknown 타입을 사용하려면 타입을 먼저 확인하는 코드를 작성해야 한다.
if (typeof a === 'number') {
let b = a + 1
}
위 코드는 if문 범위 안에서 a
의 타입이 number인 지 확인하였기 때문에, 에러가 발생하지 않는다.
if (typeof a === 'string') {
let b = a.toUpperCase();
}
마찬가지로, a
의 타입이 string인 지 확인하였기 때문에 a.toUpperCase()
가 가능하다.
아무것도 return하지 않는 함수를 대상으로 사용하는 타입
void 타입 변수에는 null과 undefined만을 할당할 수 있다.
보통 void는 따로 지정해 줄 필요가 없다.
⇒ TypeScript가 이 함수는 아무것도 return하지 않는다는 것을 자동으로 추론하기 때문에!
function hello() { // function hello(): void
console.log('x')
}
const a = hello();
a.toUpperCase(); // Err: property 'toUpperCase' does not exist on type 'void'
위 hello
함수의 경우, void는 따로 지정하지 않았지만, TypeScript가 void 타입임을 추론하였다.
void 타입을 리턴하기 때문에 toUpperCase()
를 실행할 시 에러가 발생한다.
함수가 영원히 return하지 않을 때 사용하는 타입
ex. 에러를 발생하는 함수, 무한 루프 함수 ...
function hello(): never{
return "X" // Err: Type 'string' is not assignable to type 'never'.
}
never를 return 타입으로 지정한 함수에서는 return 값을 설정할 수 없다.
function hello(): never{
throw new Error("xxx")
}
위와 같이 에러를 throw하거나, 무한 루프 함수일 때 주로 사용한다.
never는 타입이 두 가지일 수도 있는 상황에서도 발생할 수 있다.
function hello(name:string|number): never{
if(typeof name === 'string') {
name // name: string
} else if(typeof name === 'number') {
name // name: number
} else {
name // name: never
}
}
함수 hello
는 string이거나 number 일 수 있는 name
을 인자로 받는 함수이다.
if문으로 name
이 string인 경우와 number인 경우를 모두 확인해주었기 때문에, else문의 name
은 never 타입이다.
이때, 타입이 string이나 number로 올바르게 들어왔을 경우 else문은 절대 실행되지 않는다.