Reflect-metadata

reflect-metadata๋ž€

TypeScript(or JS)์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ Reflact ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•˜์—ฌ ํด๋ž˜์Šค ๋˜๋Š” ํ•จ์ˆ˜์— ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์คŒ

  • ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋Ÿฐํƒ€์ž„ ๋•Œ ์ฝ”๋“œ์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•˜๋Š”๊ฒƒ

Metadata โ†’ "๋ฐ์ดํ„ฐ์˜ ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ", "์–ด๋–ค ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ๋งŒ๋“ค์–ด์ง„ ๋ฐ์ดํ„ฐ", "๋ฐ์ดํ„ฐ์˜ ์ถ”๊ฐ€ ์ •๋ณด"

์ฆ‰, ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ์ถ”๊ฐ€๋œ ํด๋ž˜์Šค, ๋ฉ”์„œ๋“œ, ํ”„๋กœํผํ‹ฐ์˜ ๋ถ€๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

Reflect

ES6์—์„œ ๋„์ž…๋œ ๋‚ด์žฅ ๊ฐ์ฒด

๋ฆฌํ”Œ๋ ‰์…˜์€ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ์Šค์Šค๋กœ ๊ฒ€์‚ฌํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ฉ”ํƒ€ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ๋•Œ ์‚ฌ์šฉ ๋œ๋‹ค.

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ถ”๊ฐ€

key: value ๊ตฌ์กฐ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ถ”๊ฐ€

metadataKey์— ์‹๋ณ„๋˜๋ฏ€๋กœ ์›ํ•˜๋Š” ๋งŒํผ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

Reflect.defineMetadata(metadataKey, metadataValue, target);

REflect.defineMetadata(metadataKey, metadataValue, target, propertyKey);

๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ

๋Œ€์ƒ์˜ ํŠน์ • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ‚ค์— ์‹๋ณ„๋˜๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๊ฐ’ ์ถ”์ถœ

const meta = Reflect.getMetadata(metadataKey, target);

const meta = Reflect.getMetadata(metadataKey, target, propertyKet);

๊ทธ ์™ธ ๋‹ค์–‘ํ•œ api

// ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํ‚ค๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธ -> boolean
const result = Reflect.hasMetadata(metadataKey, target);

// ๊ฐœ์ฒด์˜ ์ •์˜๋œ ๋ชจ๋“  ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์˜ ํ‚ค ๊ฐ€์ ธ์˜ค๊ธฐ -> Array
const metadataKeys = Reflect.getMetadataKeys(target);

// ํŠน์ • ํ‚ค์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์‚ญ์ œ -> boolean
const result = Reflect.deleteMetadata(metadataKey, target);

๋ฉ”ํƒ€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ด๋ž€?

ํ”„๋กœ๊ทธ๋žจ์ด์ด ์ž์‹ ์˜ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด์„œ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž๊ธฐ ์ž์‹ (ํ”„๋กœ๊ทธ๋žจ)์„ ๋‹ค๋ฃจ๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ํŒจํ„ด

Decorator(@)

ํ•จ์ˆ˜ ๋˜๋Š” ํด๋ž˜์Šค ์„ ์–ธ์ด๋‚˜ ํด๋ž˜์Šค ๋ฉค๋ฒ„ ์œ„์— ์ถ”๊ฐ€ํ•˜๋Š” ์ฃผ์„์œผ๋กœ, ํ•ด๋‹น ๊ฐœ์ฒด์˜ ๋™์ž‘ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•˜๋Š” ํ•จ์ˆ˜

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ "๋ฐ์ฝ”๋ ˆ์ดํ„ฐ"์˜ ํ•ด๋ถ€ํ•™ ๋ฐ ์‚ฌ์šฉ ํŒจํ„ด

๋†€๋ž๊ฒŒ๋„ TS์—๋งŒ ์žˆ๋Š” ๊ธฐ๋Šฅ์ด ์•„๋‹Œ ๋„ค์ดํ‹ฐ๋ธŒํ•œ JS ๊ธฐ๋Šฅ(ํ‘œ์ค€ํ™” X)์ด๋ผ๊ณ  ํ•œ๋‹ค.

@ ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜, ์ „๋‹ฌ๋ฐ›์€ ์ธ์ž(ํด๋ž˜์Šค, ํ•จ์ˆ˜)์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์ฆ‰, ํด๋ž˜์Šค๋‚˜ ํ•จ์ˆ˜ ์œ„์— ๋ฐฐ์น˜ํ•˜๋ฉด ๋Ÿฐํƒ€์ž„๋•Œ ํ•ด๋‹น ํ•จ์ˆ˜, ํด๋ž˜์Šค๋ฅผ ์ธ์ˆ˜๋กœ ์‚ฌ์šฉํ•˜์—ฌ ํ˜ธ์ถœ๋˜๊ณ  ์ „๋‹ฌ๋ฐ›์€ ํ•จ์ˆ˜,ํด๋ž˜์Šค์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

@singleton()
class SingletonClass {
  //...
}

TS์—์„œ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด tsconfig.json ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ ๊ด€๋ จ ์˜ต์…˜์„ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

{
  "compilerOptions": {
    "experimentalDecorators": true, // ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ(์‹คํ—˜์ ์ธ) ์‚ฌ์šฉ ์—ฌ๋ถ€
    "emitDecoratorMetadata": true, // ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์—์„œ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ ์ถ”์ถœ ๊ฐ€๋Šฅ
  }
}

Reflect.metadata()

Reflect.metadata()๋Š” decorator(@)๋ฅผ ๋งŒ๋“œ๋Š” ๋ฉ”์„œ๋“œ

๋‚ด๋ถ€์ ์œผ๋กœ ๋ฐ์ฝ”๋ ˆ์ด์…˜ํ•˜๋Š” ๊ฐœ์ฒด์— ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” Reflect.defineMetadata๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค

@Reflect.metadata(metadataKey, metadataValue)
class DecorationClass {
  @Reflect.metadata(metadataKey, metadataValue)
  decorationMethod(){...}
}

ํ•จ์ˆ˜๋กœ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉ

function fooDecorator() {
  return Reflect.metadata('foo', 'bar');
}

@fooDecrator()
class WoongClass { }

Reflect.getMetadata('foo', WoongClass); // 'bar';

Last updated