매개변수로 받을 객체의 타입을 Annotation할 수 있습니다.
// const 함수 = (매개변수: { key: type; }) => {}
const printName = (person: { first: string; last: string }): void => {
console.log(`${person.first} ${person.last}`);
};
printName({ first: "Thomas", last: "Jankins" });
함수를 호출 할 때 객체를 인수로 사용하면, 매개변수에서 Annotation 한 타입 외의 객체 리터럴은 오류를 발생시킵니다.
하지만 사전에 변수에 초기화 하여 호출할 경우 지정된 프로퍼티 외에는 무시합니다.
const printName = (person: { first: string; last: string }): void => {
console.log(`${person.first} ${person.last}`);
};
// age는 printName 함수 매개변수의 type annotation에 포함되지 않음
// Argument of type '{ first: string; last: string; age: number; }' is not assignable to parameter of type '{ first: string; last: string; }'.
printName({ first: "Thomas", last: "Jankins", age: 32});
// age가 printName 함수 매개변수의 type annotation에 포함되지 않았지만 에러 없음
const singer = { first: "Mick", last: "Jagger", age: 473 };
printName(singer);
변수에 담길 객체의 타입을 Annotation할 수 있습니다
// let 변수: { key: 타입; } = 값
let cordinate: { x: number; y: number } = { x: 34, y: 2 };
함수의 반환값이 객체일 경우 Type Annotation을 할 수 있습니다.
// function 함수(): { key: 타입; } {
// return { key: value }
// }
function randomCoordinate(): { x: number; y: number } {
return { x: Math.random(), y: Math.random() };
}
타입에 별칭을 붙일 수 있습니다.
별칭을 생성해 사용하면 불필요한 중복을 피할 수 있습니다.
// 매개변수와 반환값에 { x: number; y: number } 객체가 중복되어 사용됨
function doublePoint(point: { x: number; y: number }): { x: number; y: number } {
return { x: point.x * 2, y: point.y * 2 };
}
type Point = {
x: number;
y: number;
};
// Point라는 별칭 사용
function doublePoint(point: Point): Point {
return { x: point.x * 2, y: point.y * 2 };
}
console.log(doublePoint({x: 1, y: 2}))
// {"x": 2, "y": 4}
type MyNum = number;
let age: MyNum = 24234;
일반적인 concrete type이 아닌 특정 값으로 type을 지정할 수 있습니다.
type Team = "read" | "blue" | "yellow"
type Health = 1 | 5 | 10
type Player = {
nickname: string,
team: Team,
health: Health
}
const zima :Player = {
nickname: "zima",
team: "blue",
health: 10
}
중첩 객체사용할 때 별칭이 없다면 가독성이 떨어지게 됩니다.
// 함수
function calculatePayout (song: {
title: string,
artist: string,
numStreams: number,
credits: {
producer: string,
writer: string
}
}): number {
return song.numStreams * 0.0033
};
// 변수에 객체 초기화
const mySong: {
title: string,
artist: string,
numStreams: number,
credits: {
producer: string,
writer: string
= {
title: "Unchained Melody",
artist: "Righteous Brothers",
numStreams: 12873321,
credits: {
producer: "Phil Spector",
writer: "Alex North",
},
};
// 함수 호출
const earnings = calculatePayout(mySong);
// 별칭 생성
type Song = {
title: string;
artist: string;
numStreams: number;
credits: {
producer: string;
writer: string;
};
};
// 함수
function calculatePayout(song: Song): number {
return song.numStreams * 0.0033;
}
// 변수에 객체 초기화
const mySong: Song = {
title: "Unchained Melody",
artist: "Righteous Brothers",
numStreams: 12873321,
credits: {
producer: "Phil Spector",
writer: "Alex North",
},
};
// 함수 호출
const earnings = calculatePayout(mySong);
프로퍼티에 ?(Optional)을 사용하여 선택적 요소로 만들 수 있습니다.
선택적 요소가 된 프로퍼티는 사용되지 않아도 오류가 발생하지 않습니다.
type Point = {
x: number;
y: number;
// z는 있어도, 없어도 상관없음
z?: number;
};
const myPoint: Point = { x: 1, y: 3, z:9 };
const myPoint: Point = { x: 1, y: 3 };
// Property 'y' is missing in type '{ x: number; z: number; }' but required in type 'Point'
const myPoint: Point = { x: 1, z:9 };
선택적 프로퍼티를 사용했다면 선택적 요소에는 값이 undefined일 수도 있다는 말과 동일합니다.
따라서 선택적 요소를 조건으로 사용할 때 먼저 선택적 요소의 값이 있는지 확인해야합니다.
const player : {
name: string,
age?: number
} = {
name: "zima"
}
// 에러 Object is possibly 'undefined'
if(player.age < 10) {
return player.age;
}
// player.age가 있는지 부터 확인
if(player.age && player.age < 10) {
return player.age;
}
readonly 제어자로 표시한 프로퍼티는 읽기만 가능하고 쓰기를 할 수 없습니다.
type User = {
readonly id: number;
username: string;
};
const user: User = {
id: 12837,
username: "zimablue",
};
// Cannot assign to 'id' because it is a read-only property
// id는 readonly이기 때문에 값 재할당 불가능
user.id = 23487104
console.log(user.id)
// 12837
readonly를 사용한 배열에는 값을 추가하지 못합니다.
const numbers: readonly number[] = [1, 2, 3, 4]
// property 'push' does not exist on type 'readonly'
numbers.push(5)
자바스크립트로 컴파일 되었을 때는 readonly가 사라집니다.
// 타입스크립트
const names: readonly string[] = ["1", "2"]
// 자바스크립트로 컴파일
const names = ["1", "2"]
&를 사용하여 교차 타입을 만들 수 있습니다.
교차 타입은 서로 다른 타입을 결합하여 새로운 타입을 만든것 입니다.
type Circle = {
radius: number;
};
type Colorful = {
color: string;
};
// &를 사용해 결합하여 새로운 타입 생성
type ColorfulCircle = Circle & Colorful;
const happyFace: ColorfulCircle = {
radius: 4,
color: "yellow",
};
type Cat = {
numLives: number;
};
type Dog = {
breed: string;
};
// &를 사용해 결합하여 새로운 타입 생성
type CatDog = Cat &
Dog & {
age: number;
};
const christy: CatDog = {
numLives: 7,
breed: "Mixed",
age: 9,
};
제한된 양의 프로퍼티 또는 키를 가지는 타입을 정의해 주는 방법입니다.
key 타입은 string, number, symbol, Template literal을 사용할 수 있습니다.
type Words = {
[key:string]: string
}
let dict: Words = {
'potato': 'food'
}
type Words = {
[key:number]: string
}
// Type '{ potato: string; }' is not assignable to type 'Words'.
// Object literal may only specify known properties, and '"potato"' does not exist in type 'Words'
let dict: Words = {
"potato": 'food'
}
키의 타입을 string으로 하면 어차피 문자 타입으로 변환되기 때문에 number, boolean, null, undefined... 타입을 키로 사용하여도 타입스크립트 경고는 발생하지 않습니다.
(심볼 제외)
type Words = {
[key: string]: string
}
let dict: Words = {
1: 'one'
}
let dict2: Words = {
true: 'false'
}
let dict3: Words = {
null: 'no'
}
let dict4: Words = {
undefined: 'defined'
}
console.log(dict["1"])
// "one"
console.log(dict["true"])
// "false"
console.log(dict3["null"])
// "no"
console.log(dict["undefined"])
// "defined"
자바스크립트에서 키의 타입은 주로 문자열과 심볼이지만, 다른 타입의 값을 객체의 키로 사용하려고 하면 JavaScript에서 자동으로 해당 값이 문자열로 변환됩니다. 예를 들어, 숫자나 불리언 값을 객체의 키로 사용하면 자동으로 문자열로 변환됩니다.