[TS] Object generic 심화 : typeof

강원지·2023년 4월 1일

타입스크립트

목록 보기
4/4

typeof

keyof는 Object의 key들의 lieteral 값들을 가져온다.

interface Person {
    name: string
    age: number
}

type Test = keyof Person // ("name", "age")


function setProperty<T, K extends keyof T>(obj: T, key: K, value: T[K]): void {
    obj[key]=value
}

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
    return obj[key]
}

//예시1
const person:Person={
  name:"wonji",
  age:26
}
setProperty(person, 'name', 'Anna')

console.log(getProperty(person,'name'))//'Anna'

//예시2
const student={
  name:""
}
setProperty(student,'name','kimbap')
console.log(student)

구현 문제1

질문

T에서 K 프로퍼티만 선택해 새로운 오브젝트 타입을 만드는 내장 제네릭 Pick<T, K>을 이를 사용하지 않고 구현하세요.

예시:

interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = MyPick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
    title: 'Clean room',
    completed: false,
}

정답

type MyPick<T,K extends keyof T>={
  [key in K]=T[key]
}

이것저것

type Food={
  name:string,
  price:number
}

//obj의 일부 키만 사용
type FoodPick<T,K extends keyof T>={
  [key in K] : T[key]
}
type FoodPrint={
  <T>(arr:T[]):void
}
type Kimbap=FoodPick<Food,"name">
const kimbap:Kimbap={
  name:"kimbap"
}

//obj 배열 만들고 출력
const foodFestival:Food[]=[]
const bibibap:Food={
  name:"bibibap",
  price:3000
}
const icecream:Food={
  name:"icecream",
  price:2000
}
foodFestival.push(bibibap)
foodFestival.push(icecream)
const foodprint:FoodPrint=(foodFestival)=>{
  foodFestival.forEach((food)=>console.log(food))
}
foodprint(foodFestival)

//obj key에 대한 값 출력
const getInfo = <T, K extends keyof T>(food: T, info: K): void => {
  console.log(food[info]);
}
// function getInfo<T,K extends keyof T>(food:T,info:K):void{
//   console.log(food[info]) 
// }
getInfo(icecream,"price")
getInfo(icecream,"name")

구현 문제2

질문

배열(튜플)을 받아, 각 원소의 값을 key/value로 갖는 오브젝트 타입을 반환하는 타입을 구현하세요.

예시:

const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const

type result = TupleToObject<typeof tuple> 
//expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}

정답

type TupleToObject<T extends readonly (number|string)[]> = {
  [key in T[number]]: key
}

0개의 댓글