사이드 프로젝트에서 API 응답 데이터를 처리하기 위해 제네릭 기반의 유틸리티 함수를 구현하고 있습니다.
코드:
interface BaseResponse {
id: string;
}
function getValue<T extends BaseResponse, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
const data = { id: "123", name: "TypeScript", version: 5.0 };
const result = getValue(data, "name");
오류: `Type '{ id: string; name: string; version: number; }' does not satisfy the constraint 'BaseResponse'.` (특정 조건에서 `T`가 `BaseResponse`를 확장하지만 `K`를 통한 접근 시 타입 가드가 제대로 작동하지 않음)
시도: `K`에 `string` 타입을 명시적으로 추가하거나 `T`를 `any`로 캐스팅하여 테스트함.
질문: `T extends BaseResponse` 제약 조건이 있는 상태에서 `keyof T`를 통해 동적으로 값에 접근할 때, 타입 추론이 정확히 `T[K]`로 유지되게 하려면 어떻게 타입을 정의해야 합니까?
댓글10
-
빗방울
2026.10.30 16:37
-
빗방울
2026.10.30 16:59
내 생각엔 T에 Index Signature를 명시적으로 넣어줘야 할 것 같은데.
그거 안 해주면 TS가 구조적 타이핑 때문에 헷갈려 하더라고요.
한번 시도해보세요.
-
빗방울
2026.10.30 18:24
맞음 그거 넣으면 해결될 것 같네요.
아니면 record 타입으로 한 번 감싸서 넘겨보는 건 어떨까요ㅋㅋ
-
빗방울
2026.10.30 18:58
이거 혹시 const assertion 써보셨나요?
데이터 선언할 때 as const 붙여서 리터럴 타입으로 고정시키면 추론 더 잘 될 것 같은데ㅋㅋ 한번 해보셈
-
빗방울
2026.10.30 19:02
이거 혹시 TS 버전 문제 아님? 최신 버전으로 올려보거나 아예 Generic 대신 함수 오버로딩 써보는 거 추천함ㅋㅋ
-
빗방울
2026.10.30 19:35
이거 T 대신 T & Record<string, any> 이런 식으로 교집합 처리해보셈.
그렇게 하면 제약 조건 유지하면서 인덱스 접근 가능할 것 같은데ㅋㅋ
한번 해보시고 알려주세요.
-
빗방울
2026.10.30 19:44
이거 그냥 BaseResponse를
extends 하는 대신 intersection 타입으로 묶어서 넘겨보셈ㅋㅋ
아니면 아예 헬퍼 타입 하나 만들어서 추론 강제하는 게 빠를듯ㄷㄷ
-
빗방울
2026.10.30 20:09
혹시 BaseResponse를 type alias로 바꿔서 시도해보셨나요? interface보다 type이 가끔 추론 더 유연하게 잡힐 때가 있더라고요ㅋㅋ 한번 해보셈
-
빗방울
2026.10.30 20:45
이거 그냥 T[K] 대신 return 값 타입을 명시적으로 지정해주거나 generic 인자를 하나 더 추가해서 넘겨보는 건 어떠신가요ㅋㅋ 내 생각엔 추론 순서 문제인 것 같아서 그렇게 하면 잡힐 것 같네요.
-
빗방울
2026.10.30 21:08
이거 그냥 `getValue` 함수 호출할 때 제네릭 인자 명시적으로 `<typeof data, "name">` 이렇게 박아넣으면 해결되지 않나요ㅋㅋ
귀찮긴 한데 추론 꼬일 땐 그게 제일 확실함ㄷㄷ
한번 해보셈.
모든 이야기1488
가벼운 안부부터 깊은 생각까지, 함께 나눠요.
이거 타입스크립트 고질병인듯.
제네릭 대신 맵드 타입으로 한 번 꼬아보거나 그냥 as any 쓰는 게 정신건강에 이롭네요.
아니면 T를 직접 안 쓰고 interface로 따로 빼서 정의해보세요.