유동적인 타입 설정
이란, 기본 타입이나 별칭 또는 인터페이스로 만든 원래 존재하던 타입들을
상황에 따라 유동적으로 다른 타입으로 변환하는 것을 말하고,
이전에 정리했던 제네릭
도 그 방법 중 하나이며
순서대로 사용법을 정리해보고자 한다.
객체
, 배열
, 튜플
타입으로부터 특정 프로퍼티나 특정 요소의 타입만 추출하는 것이다.
interface Post {
title: string;
content: string;
author: {
id: string;
name: string;
age: number;
}
}
const post: Post = {
title: '제목',
content: '본문',
author:{
id: '1',
name: 'jaehan',
age: 31
}
}
// author 출력
const printAuthorInfo = (author: ??? ) => {
console.log(`${author.name} - ${author.age}`)
}
post
객체의 author
정보를 출력해주는 함수 printAuthorInfo
가 있다.
이때, 매개변수 author
의 타입을 지정해 주어야하는데
const printAuthorInfo = (author: {id: string, name: string, age: number} ) => {
console.log(`${author.name} - ${author.age}`)
}
이렇게 직접 타입을 지정해주어도 문제는 없지만
원본 타입인 Post
의 author
가 변경 될 경우 author
를 매개변수로 갖는 모든 함수들을 일일이 수정해 주어야 한다.
이때, 인덱스드 엑세스 타입
을 사용하면 간단하게 해결할 수 있다.
const printAuthInfo = (author: Post['author']) => { // ✅
console.log(`${author.name} - ${author.age}`)
}
한단계 더 들어가 author
의 name
타입에 접근하고 싶다면
const printAuthorInfo = (author: Post['author']['name']) => { // ✅
console.log(`${author}`)
}
이렇게 사용하면 된다.
배열 타입에서 하나의 요소 정보를 가져오기 위해서는
배열타입 [number]
형식으로 사용하면 된다.
type PostList = {
title: string;
content: string;
author: {
id: string;
name: string;
age: number;
}
}[]
const post: PostList[number] = { // ✅
title: '제목',
content: '본문',
author:{
id: '1',
name: 'jaehan',
age: 31
}
}
const printAuthorInfo = (author: PostList[number]['author']) => { // ✅
console.log(`${author.name} - ${author.age}`)
}
PostList[number]
는 PostList 배열 타입의 하나의 요소의 타입을 가져온다는 뜻이다.
keyof
는 객체 타입에서만 사용이 가능한 연산자이다.
특정 객체 타입의 프로퍼티 키들을 스트링 리터럴 유니온 타입으로 추출하는 연산자이다.
말이 어려운데, 코드를 보면 간단하다.
interface Person {
name: string;
age: number;
}
// 객체와 key 값을 받아 return
const getPropertyKey = (person: Person, key: keyof Person) =>{// ✅
return person[key]
}
const person: Person ={
name: 'jaehan',
age: 31
}
getPropertyKey(person, 'age')
위의 코드에서 매개변수 key의 타입을 keyof Person
으로 선언함으로써 'name' | 'age'
로 설정된다.
이는 Person
타입의 프로퍼티 키들을 스트링 리터럴 유니온 타입으로 추출 된 모습이다.
기존의 객체 타입으로부터 새로운 객체 타입을 만들 때 사용한다.
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = {
readonly [key in keyof Person]?: Person[key] // ✅
}
뭔가 복잡해 보이지만 하나하나 뜯어보면 간단하다.
Person
타입과 동일한 타입을 만드는데, 모든 프로퍼티에 readonly 와 Optional 을 추가해준 것이다.
프로퍼티 키는 keyof
연산자로 받아오고 각각의 타입은 ?: Person[key]
로 정의 한 것이다.
기존의 스트링 리터럴 타입을 기반으로 정해진 패턴의 문자열만 포함하는 타입이다.
type Color = 'red' | 'black' ;
type Animal = 'dog' | 'cat' ;
type ColoredAnimal = `${Color}-${Animal}`
이렇게 선언 할 경우
ColoredAnimal
타입은 'red-dog' | 'red-cat' | 'black-dog' | 'black-cat'
로 된다.