type CoffeePrice = {
[K in CoffeeName]: number;
};
type CoffeeName = "americano" | "latte" | "ade";
const obj: CoffeePrice = {
// ~~~ error Property 'ade' is missing in type '{ americano: number; latte: number; }' but required in type 'CoffeePrice'.ts(2741
americano: 10,
latte: 10,
};
- ade 가 없어서 완전히 일치하지 않기 때문에 오류가 나온다.
해결법
? 연산자를 넣어주거나
부분만 포함하겠다는 partial 키워드를 넣어주면 된다.
위의 기초 연습을 토대로 내 코드를 리팩터링 하기로 했다.
문제의 코드,tf를 이용해 type 가드를 해줬음에도 오류가 난다.
type은 잘 추론하고 있다
Partial키워드의 타입은 이렇다.
Partial 키워드를 사용하면 undefined도 올 수 있다.
하지만 위의 코드에서 나는 tf = type&&propertyValues 를 이용해 타입가드를 했는데도 undefined로 추론하고 있는데 왜 오류가 나는걸까 ?
심지어 테스트 코드로 테스트해보시 Partial 키워드를 사용하는 d 에 값을 할당하는건 문제가 없었다.
그럼 대체뭐지?
type의 타입인 HousePriceObjectType을 살펴보자
나는 여기서 문제를 생각했다 …
나는 houseType을 통해 나온 값인 propertyValues 와 type 객체가
같은 key값을 가진다는걸 알고있다.
하지만 ts는 서로 다른 함수에서 태어난 두 값을 연관시켜서 추론하지 못하는거다
같은 HousePriceType을 사용한다고 해도
type의 키값엔 kbPrice가 있어도
PropertyValues엔 kbPrice가 없을 수도 있으니까!
계속 Undefined가 떳던 것이다.
그림으로 설명해보자면
그렇다면 해결방법은 ?
이런식으로 type.buildingPrice처럼 타입가드를 하나하나 걸어주면 해결된다.
이런방식으로 하나하나 타입가드를 거는건 된다. 다만 type[type] 지정은 되지않는다.
로직을 단순하게 보기위해 비슷한 환경을 구성했다.
type CoffeePrice = {
[K in CoffeeName]: number;
};
type CoffeeName = "americano" | "latte" | "ade" | "blackcoffee";
type PriorityType = {
table1: Partial<CoffeePrice>;
table2: Partial<CoffeePrice>;
};
const PRIORITY: PriorityType = {
table1: {
americano: 1,
latte: 1,
},
table2: {
americano: 1,
latte: 2,
},
};
const returnFunction = (
c: "table1" | "table2"
): PriorityType[keyof PriorityType] => {
return PRIORITY[c];
};
const cafe = (d: Partial<CoffeePrice>) => {
const c = "table1";
const a = returnFunction(c);
let priority: number = 1000;
for (const key of Object.keys(d) as Array<CoffeeName>) {
if (a[key]) {
priority = a[key];
~~~~~~~~~~ error
console.log(key);
}
console.log(key);
d[key] = 10;
}
};
비슷한 로직으로 만든 다른환경 역시나 에러가 난다.
이렇게 세조각으로 나누고 type을 분명하게 해줬다.
그리고 스택오버플로우에 Object.keys()의 타입을 구하는법을 검색해봤는데 as Array<keyof typeof type> 을 쓰면된다고한다.
예를들어 MultiApartOfficeElderHousePriorityType 타입이라면
즉 type의 typeof 인 MultiApartOfficeElderHousePriorityType 의 key 값인
const calculateHousePriceByPriority = (
houseType: HouseType,
propertyValues: Partial<HousePricesType>,
housePrices: HousePricesType
) => {
let priority: number | undefined = 1000;
let housePrice = 0;
let type = findPriorityType(houseType);
for (const key of Object.keys(type) as Array<keyof typeof type>) {
if (type[key] < priority) {
priority = type[key];
housePrice = calculateHousePrice(
key,
propertyValues[key]!.value,
housePrices
);
housePrice *= LOAN_LATIO;
}
}
return housePrice;
};
as Array<keyof typeof type> 는
예를들어 MultiApartOfficeElderHousePriorityType 타입이라면
즉 type의 typeof 인 MultiApartOfficeElderHousePriorityType 의 key 값인
kbPrice … 을 가져오는거다.
그리고 그걸 배열로 만들어 Object.keys의 타입으로 선언해준다.
매번 저 긴코드를 치기도 귀찮고 보기도 좋지 않아서
이런식으로 util 함수로 만들었다.
그리고 위처럼 리팩터링했다! 끝!
'Develog > Front' 카테고리의 다른 글
[꼬랑지랑] next.js 사이트 개선기 (1) (0) | 2024.07.13 |
---|---|
[우아한-Tech 스터디] Framer-motion을 이용한 애니메이션으로 화려한 웹 페이지 만들기 - 2주차 - (1) | 2024.06.20 |
Drag AND Drop (react.js)구현하기 - 1 (0) | 2023.07.09 |
React 중첩라우팅 (0) | 2022.07.10 |
[Udemy Web 부트캠프] 섹션 19,20,21 루프의 구조, 함수란?, 함수 레벨업 (0) | 2022.03.29 |