즐코

generic / class의 public, protected, private 본문

TypeScript

generic / class의 public, protected, private

YJLEE_KR 2022. 6. 9. 20:12

 

Generic이란 ?

- 데이터의 타입을 일반화한다(generalize)

- 데이터 타입을 확정지어놓지 않고 유동성 있게 여러 타입을 사용할 수 있게 해줌

- 선언 시점이 아니라 생성 시점에 타입을 명시하여 고정된 타입이 아니라 다양하고 유동성있는 타입을 사용할 수 있도록 해준다.

-  한번의 선언으로 다양한 타입에 '재사용'이 가능하다는 장점이 있다.

 

any가 Generic과 다른 점 

- 함수의 반환 타입을 유추하기 어려움

- 매개변수의 프로퍼티를 체크할 수 없다

 

제네릭 함수 쓰는 방법

- 함수명 뒤에 <T> 를 추가 (Type의 T에서 따온 거고, 아무 문자나 적어도 된다)

- 해당 T를 매개변수의 타입이나 반환 타입으로 설정이 가능하다. 

 

// @types/Failable.d.ts

declare type Result<R> = { isError : false; value : R };
declare type Failure<E> = { isError : true; error : E };
declare type Failable<R, E> = Result<R> | Failure<E>

 

제네릭 <> 안에 들어간 string은 각 Result, Failure가 반환하는 객체의 value, error값이다. 

따라서, 아래 checkNum 함수의 객체 반환값 안에서 value, error값으로 string 대신 다른 타입을 넣으면 빨간줄이 뜬다.

 

function checkNum(num: number): Failable<string, string>{
	if(num !== 5) return { isError: true, error: `${num}은 틀렸다` }
    return { isError: false, value : `${num}이 맞음` }
}

const result = checkNum(1);
if (result.isError) console.log(result.error);

 

타입스크립트에서 class를 생성해줄 때

 

1. class가 찍어낼 객체의 속성 값들의 타입을 먼저 지정해준다. (접근 제한자 public, private, protected 사용)

2. constructor(인자1, 인자2, ...) 인스턴스를 생성할 때 받을 인자에 대해서도 타입을 지정해준다.

 

// generic.ts

export class Output{
	public address : string;
	public amound : number;
    
    constructor(_address: string, _amount: number) {
    	this.address = _address;
    	this.amount = _amount;
  }
}

export class Input{
	public signature : string;
    
    constructor(_output: Output){
    	this.signature = Input.sum(_output);
    }
    
    static sum(_output : Output) : string{
    	const value: string = Object.values(_output).join('');
        return value;
    }
}

 

테스트 돌려보기

 

// generic.test.ts

import { Output, Input } from "./generic";

describe('Class Output 검증', ()=>{
	let output: Output;
	let input: Input;
    
    it('Output instance 생성 확인', ()=>{
    	output = new Output('7722', 10);
        console.log(output); // Output { address: '7722', amount: 10 }
    })
    
    it('Input instance 생성 확인', ()=>{
    	input = new Input(output);
        console.log(output); // Input { signature: '772210' }
    })
    
    it("txToString() 구현", () => {
    function txToString<T>(data: T) {
      const result = Object.entries(data);
      const a = result.map((v) => {
        return v.join("");
      });
      console.log(a);
      return a.join("");
    }
    const inputResult = txToString<Input>(input);
    console.log(txToString(input));
  });
});

// [ [ 'address', '7722' ], [ 'amount', 10 ] ]
// ['address7722', 'amount10']
// address7722amount10

 

접근 제한자 (Access modifier)

: public, private, protected 사용

 

접근 가능성 public protected private
클래스 내부 O O O
자식 클래스 내부 O O X
클래스 인스턴스 O X X

 

// accessModifier.ts

export class Family {
  public me: string;
  protected sis: string;
  private cat: string;

  constructor(me: string, sis: string, cat: string) {
    this.me = me;
    this.sis = sis;
    this.cat = cat;
  }
}

 

새로운 인스턴스 생성 시 아래처럼 public으로 지정해준 속성만 접근할 수 있었다.

 

// accessModifier.test.ts

import { Family } from "./accessModifier";

describe("public, protected, private 테스트", () => {
  it("우리집테스트", () => {
    const myFamily = new Family("yj", "hj", "hoochu");
    console.log(myFamily); // Family { me: 'yj', sis: 'hj', cat: 'hoochu' }
    console.log(myFamily.me); // yj
    console.log(myFamily.sis); // 접근 불가능
    console.log(myFamily.cat); // 접근 불가능
  });
});

 

하지만 protected로 지정한 경우, 아래와 같이 자식 클래스 내부에서 접근하는건 가능했다.

 

// accessModifier.ts

export class BabyFamily extends Family {
  constructor(me: string, sis: string, cat: string) {
    super(me, sis, cat);
    console.log(this.me); // 접근 가능
    console.log(this.sis); // 접근 가능 
    console.log(this.cat); // 접근 불가능
  }
}

'TypeScript' 카테고리의 다른 글

TypeScript - tsconfig.json 기본설정 + test를 위한 jest  (0) 2022.06.09
Comments