제네릭 타입을 사용하는 유틸리티 함수에서 객체의 특정 속성을 업데이트하고 새로운 객체를 반환하려 합니다.
코드:
interface User {
id: number;
name: string;
}
function updateProperty<T extends object, K extends keyof T>(obj: T, key: K, value: T[K]): T {
return { ...obj, [key]: value };
}
const user: User = { id: 1, name: "Kim" };
const updatedUser = updateProperty(user, "name", "Lee");
오류: `Type 'T' is not assignable to type 'T'. Type '{ [key: string]: any; }' is not assignable to type 'T'.` (컴파일 에러 발생)
시도: 반환 타입을 `any`로 지정하거나 `as T`로 타입 단언을 사용하여 해결했으나, 타입 안정성이 떨어지는 문제가 있습니다.
질문: 타입 단언을 사용하지 않고 제네릭 함수 내에서 계산된 속성 이름(Computed Property Name)을 사용하여 `T` 타입을 정확하게 반환하는 방법은 무엇입니까?
댓글8
-
빗방울
2026.10.30 09:52
-
빗방울
2026.10.30 10:38
ㄹㅇ 이거 진짜 킹받는 부분임ㅋㅋ
내 생각엔 그냥 타입 단언 쓰고 넘어가는 게 제일 속 편한 것 같은데 ㄷㄷ
-
빗방울
2026.10.30 12:04
ㄹㅇ 꼬아 쓰다 보면 나중엔 타입 정의하는 게 더 일인듯ㅋㅋ
걍 적당히 타협하고 라이브러리 쓰는 게 정신건강에 제일 좋긴 하겠네요ㄷㄷ
-
빗방울
2026.10.30 10:08
이거 그냥 반환 타입을 `T`가 아니라 `Partial<T>` 섞어서 정의하거나
함수 오버로딩 쓰면 좀 나을 수도 있을 듯요ㅋㅋ 한번 시도해보셈
-
빗방울
2026.10.30 11:00
오버로딩까지 가기엔 너무 빡세지 않나요ㅋㅋ
그냥 `as T` 때리는 게 국룰인듯요 ㄷㄷ
-
빗방울
2026.10.30 11:43
오버로딩은 진짜 오버인 것 같고ㅋㅋ
그냥 리턴 타입 살짝 비틀어서 푸는 게 그나마 현실적이겠네요ㄷㄷ
-
빗방울
2026.10.30 12:54
이거 그냥 반환 타입을 `T & { [P in K]: T[P] }` 이런 식으로 맵드 타입 써서 정의하면
컴파일러가 좀 더 잘 알아먹지 않을까요ㅋㅋ
아니면 그냥 포기하고 `as T` 박는 게 답인 듯ㄷㄷ
-
빗방울
2026.10.30 12:57
맵드 타입 써도 결국 내부에서 객체 새로 생성하면 타입 안 맞다고 징징거릴 것 같은데ㅋㅋ 그냥 `as T` 박는 게 정신건강에 제일 이롭긴 하겠네요ㄷㄷ
모든 이야기1455
가벼운 안부부터 깊은 생각까지, 함께 나눠요.
이거 TS 고질병이라 빡치네요.
그냥 반환 타입을 `T & Record<K, T[K]>` 이런 식으로 꼬아서 풀어야 될 듯요.
아니면 그냥 라이브러리 쓰는 게 정신건강에 이롭습니다ㅋㅋ