Front/typescript

타입 조작

akii 2023. 8. 25. 15:24
반응형
타입 조작
: 원래 존재하던 타입들을 타입스크립트의 문법을 이용해서 상황에 따라 각각 다른 타입으로 변환하는 기능

 

  1. 제네릭
  2. 인덱스드 엑세스 타입
  3. keyof 연산자 
  4. Mapped(맵드) 타입
  5. 템플릿 리터럴 타입
  6. 조건부 타입

 


 

인덱스드 엑세스 타입 (Indexed Access Type)

: 인덱스를 이용해 다른 타입내에 특정 프로퍼티의 타입을 추출하는 타입, 객체, 배열, 튜플 타입에 사용
  • 객체 타입 - 프로퍼티의 타입이 추가/수정 -> 즉시반영, index에 들어가는 문자열은 값이 아닌 타입
interface Post {
  title: string;
  content: string;
  author: {
    id: number;
    name: string;
    age: number;
  };
}

// Post 타입으로부터 특정 프로퍼티의 타입만 추출
function printAuthorInfo(author: Post["author"]) {   // "author"(스트링 리터럴 타입) -> index 라고 명칭
  //(author: Post["author"]["id"]) -> 중첩 가능 (아이디만 가져올때)
  console.log(`${author.name} - ${author.id}`); 
}

const post: Post = {
  title: "제목",
  content: "내용",
  author: {
    id: 1,
    name: "나재민",
    age: 24,
  },
};

printAuthorInfo(post.author);

 

  • 배열 -  배열 타입에서 하나의 요소의 타입만 추출, 인덱스에 Number Literal 타입 / number 타입 넣음
type PostList = {
  title: string;
  content: string;
  author: {
    id: number;
    name: string;
    age: number;
  };
}[];

function printAuthorInfo(author: PostList[number]["author"]) {
  console.log(`${author.name} - ${author.id}`);
}

const post: PostList[number] = {   // == PostList[0], 0은 값이 아닌 타입
  title: "제목",
  content: "내용",
  author: {
    id: 1,
    name: "나재민",
    age: 24,
  },
};

printAuthorInfo(post.author);

 

  • 튜플 - 인덱스 에 number 타입 -> 배열요소의 타입을 추출
type Tup = [number, string, boolean];
type Tup0 = Tup[0];  // number
type Tup1 = Tup[1];  // string
type Tup2 = Tup[2];  // boolean
//type Tup3 = Tup[3];  // 길이가 고정 -> 존재하지 않은 인덱스 추출 ❌

// 튜플타입안의 모든 타입의 최적의 공통 타입 추출
type TupNum = Tup[number];  // number | string | boolean (유니온 타입)

 


 

Keyof 연산자 (Keyof Operator)

: 특정객체의 타입으로 부터 프로퍼티의 key들을 스트링 리터럴 유니온 타입으로 추출, 타입에만 사용 가능
interface Person {
  name: string;
  age: number;
}

// Person객체 타입 으로부터 모든 프로퍼티의 키를 유니온타입으로 추출
function getPropertyKey(person: Person, key: keyof Person) {  // "name" | "age"
  return person[key];
}

const person: Person = {
  name: "정재현",
  age: 27,
};

getPropertyKey(person, "name");

 

typeof 연산자 - 타입을 정의할때 사용하면 특정변수의 타입을 추론해줌

type Person = typeof person;  // {name:string, age:number}

function getPropertyKey(person: Person, key: keyof typeof person) {
  return person[key];  // "name" | "age"
}

const person = {
  name: "정재현",
  age: 27,
};

 


 

맵드 타입(Mapped Type)

: 기존의 객체타입을 가지고 새로운 객체 타입을 만듦, [key in 객체의 프로퍼티 key]: value[]
interface User {
  id: number;
  name: string;
  age: number;
}

type PartialUser = {
  [key in "id" | "name" | "age"]?: User[key];  // ? 선택적 프로퍼티
};

type BooleanUser = {
  [P in "id" | "name" | "age"]: boolean;    // key 문자는 상관 없음
};
type BooleanUser = {
  [key in keyof User]: boolean;
};

// 한명의 유저 정보를 수정하는 기능
function updateUser(user: PartialUser) {}

updateUser({
  age: 25,
});

type ReadonlyUser = {
  readonly [key in keyof User]: User[key];
};

// 한명의 유저 정보를 불러오는 기능
function fetchUser(): ReadonlyUser {
  return {
    id: 1,
    name: "정재현",
    age: 27,
  };
}

const user = fetchUser();
user.id = 1;   // ❌ readonly

 


 

탬플릿 리터럴 타입 (Template Literal Type)

: 스트링 리터럴 타입을 기반으로 특정 패턴을 갖는 문자열 타입을 만드는 기능

type Color = "red" | "black" | "green";   // 스트링 리터럴 타입의 유니온 타입
type Animal = "dog" | "cat" | "chicken";

type ColoredAnimal = `${Color} - ${Animal}`; // 백틱 + ${타입명}

 

반응형