PSD( Private-Self-Development )

타입스크립트 데코레이터 본문

Frontend/Typescript

타입스크립트 데코레이터

chjysm 2022. 9. 29. 13:51

데코레이터

클래스, 메서드, 접근자, 프로퍼티, 파라미터에 기능을 추가해주는 선언

function exampleDecorator(exampleString: string){  //데코레이터 팩토리
		...
		return function (exampleFunction :Function){  // 데코레이터 함수
				...
		}
}

@exampleDecorator()
class exampleClass {...}

믹스인

  • 다른 클래스의 부모클래스가 되지 않으면서 다른 클래스에서 사용할 수 있는 메서드를 포함하는 클래스.
  • 단독으로 사용할수 없으며 다른 클래스에 추가되어 사용
  • TS는 다중상속을 지원하지 않지만 믹스인을 사용해 구현 가능

타입스크립트의 믹스인:

{new(…args: any[]):{}}

데코레이터와 믹스인

function exampleDecorator(exampleString: string){  //데코레이터 함수
		...
		return function <T extends {new(…args: any[]):{}}>(target :T){  // 데코레이터 본문
				return class extends target{  // 데코레이터 클래스 재선언
						... 프로퍼티 추가, 메서드 재선언 ...
				}
		}
}

@exampleDecorator()
class exampleClass {...}

데코레이터의 합성

데코레이터는 하나의 선언에 동시에 여러 개의 데코레이터를 적용할 수 있음. 따라서 적용 순서에 따라 수행 순서가 달라짐

function decoA() {
    console.log('decoA factory');
    return function(target: Function) {
        console.log('decyA decorator')
    }
}

function decoB(target: Function) {
    console.log('decoB decorator');
}

function decoC() {
    console.log('decoC factory');
    return function(target: Function) {
        console.log('decoC decorator');
    }
}

//호출 순서
@decoA
@decoB
@decoC

//결과
> decoA factory
> decoB factory
> decoC factory
> decoC decorator
> decoB decorator
> decoA decorator

매핑타입

기존의 타입에 새로운 타입을 변환시켜줌. 기존의 변수들의 타입을 한번에 변환 시켜주는 장점이 있지만 interface안의 모든 변수의 타입을 한꺼번에 변경 해야 하는 경우가 자주 있을까?

interface Person{
		name: string
		age: number
}

type ReadyOnly<T> = {
	readyonly [P in keyof T]: T[P];
}

interface Person{
		readonly name: string
		readonly age: number
}

실제로 사용될 가능성이 높은 코드

type Subset<T> = {
  [K in keyof T]?: T[K];
}

const ageOnly: Subset<Person> = { age: 23 };
const nameOnly: Subset<Person> = { name: 'Tony' };
const ironman: Subset<Person> = { age: 23, name: 'Tony' };
const empty: Subset<Person> = {};