인프런 커뮤니티 질문&답변

민혁님의 프로필 이미지

작성한 질문수

[코드팩토리] [초급] 8시간만에 끝내는 코드팩토리의 Typescript 완전정복 풀코스

리플렉션과 데코레이터 사용시 의문점

작성

·

36

0

안녕하세요

리플렉션과 데코레이터를 공부하면서 잘 이해한건지 궁금합니다.

const restrictParamValueKey = Symbol('restrict-param-value')

interface RestrictionInfo<T> {
    index: number
    restrictValues: T[]
}

function RestrictParamValue<T>(restrictValues: T[]) {
    return (target: any, propertyKey: string, index: number) => {

        console.log(`${target} ${propertyKey}${index}`)
        const prevMeta = Reflect.getOwnMetadata(restrictParamValueKey, target, propertyKey) ?? []

        const info: RestrictionInfo<T> = {
            index,
            restrictValues
        }

        Reflect.defineMetadata(restrictParamValueKey, [
            ...prevMeta,
            info
        ], target, propertyKey)
        console.log(Reflect.getOwnMetadata(restrictParamValueKey, target, propertyKey))
    }
}

메서드의 파라미터 데코레이터 사용시 Reflect.defineMetadata로 메타데이터를 정의하는데 3번째 파라미터로 target 4번째로는 propertyKey를 넣는 이유가 target는 클래스의 프로토타입 이며 propertyKey는 메서드가 target 클래스의 프로토타입의 메서드이기 때문일까요?

추가로 메서드 데코레이터와 파라미터 데코레이터에서의 target, propertyKey는 동일한게 맞을까요?

 

답변 2

0

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

안녕하세요!

Reflect.defineMetadata(metadataKey, metadataValue, C.prototype, "method");

위 정의가 defineMetadata의 정의입니다.

target과 propertyKey를 출력 해보니 같은 값이 나온다는 질문일까요?

감사합니다!

민혁님의 프로필 이미지
민혁
질문자

답변 감사합니다 출력해보니 메서드, 파라미터 데코레이터의 target, propertyKey의 출력 값이 같은게 맞을까요?

 

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

다양하게 시도 해봤는데 "같다"를 재연 할 수 없어서 어떻게 대답 해드려야 할지 모르겠습니다.

target은 적용된 class고 propertyKey는 적용된 파라미터 키값입니다.

어떻게 적용하면 같게 나오게 할 수 있을까요? 말씀 주시면 제가 다시 분석해서 답변 드리도록 하겠습니다.

감사합니다!

민혁님의 프로필 이미지
민혁
질문자

스크린샷 업로드 했습니다

스크린샷 2024-11-13 오전 9.25.36.png스크린샷 2024-11-13 오전 9.25.43.png
코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

저와 같은 출력 결과로 보입니다. target은 클래스고 propertyKey는 파라미터 이름으로 보입니다. 제가 설명드린 것과 일치하는 정상적인 상황 같은데 어떤게 같다는 말씀이실까요?

민혁님의 프로필 이미지
민혁
질문자

파라미터 데코레이터의 target , propertyKey의 값과 메서드 데코레이터의 target, propertyKey의 값이 동일한게 맞는건지 궁금합니다.

코드팩토리님의 프로필 이미지
코드팩토리
지식공유자

아 이제 이해했습니다. target === propertyKey 질문인 줄 알았는데 param.target === method.target && param.propertyKey === target.propertyKey 가 질문 맞나요?

target은 같은 클래스에 데코레이팅 한다면 같은 값이 나오고 propertyKey는 같은 메서드에 데코레이팅 한다면 같은 값이 나옵니다.

민혁님의 프로필 이미지
민혁
질문자

네넵 맞습니다 마지막에 말씀해주신걸로 이해했습니다

0

안녕하세요, 인프런 AI 인턴입니다.

TypeScript에서 데코레이터를 사용하면서 Reflect 메소드로 메타데이터를 다룰 때, 발생할 수 있는 혼란에 대해 질문해 주신 것 같습니다. 해당 개념을 명확히 정리해 드리겠습니다.

메타데이터와 데코레이터의 사용

  1. Reflect.defineMetadata 사용: 이 함수는 메타데이터를 대상(target)에 정의합니다. 여기서:
    • target은 종종 클래스의 프로토타입을 가리킵니다. 이는 인스턴스가 아닌 클래스 자체나 그 프로토타입에 메타데이터를 저장하는 것이 대부분의 경우 사용 목적에 부합하기 때문입니다.
    • propertyKey는 메타데이터가 연결될 특정 메서드의 이름입니다.

따라서, Reflect.defineMetadata(restrictParamValueKey, [...], target, propertyKey)와 같이 호출하면 해당 메서드에 메타데이터를 저장하게 됩니다.

  1. 데코레이터의 targetpropertyKey:
    • 메서드 데코레이터target은 클래스의 프로토타입을 나타냅니다. 이로 인해 메서드 데코레이터의 propertyKey는 해당 프로토타입에 정의된 메서드의 이름이 됩니다.
    • 파라미터 데코레이터의 경우도 유사한 맥락에서 작동합니다. 파라미터 데코레이터의 target도 클래스의 프로토타입을 가리키고 propertyKey는 메서드의 이름이 됩니다. 이는 메서드의 특정 인덱스의 파라미터에 메타데이터를 추가하기 위함입니다.

정리하자면, 메서드와 파라미터 데코레이터에서 target이 클래스의 프로토타입을 가리키고 propertyKey는 해당 메서드의 이름을 가리키는 점이 동일합니다.

이해에 도움이 될 만한 기존 질문과 답변을 추천드리니 참고해 주세요:

이 정보를 통해 데코레이터와 메타데이터의 상호작용 방식에 대한 이해가 도움이 되길 바랍니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

민혁님의 프로필 이미지

작성한 질문수

질문하기