타입을 임의로 정해서 사용자가 함수를 사용할 때 직접 지정해줄 수 있다.

 

제네릭 함수 선언 - 동시에 여러 타입을 지정해 줄 수 있다.

function helloBasic<T, U>(message: T, commet: U): T {
  return message;
}

타입을 선언하여 사용하는 방법 - 선언한 타입과 반드시 같은 타입을 입력해주어야 한다.

// 직접 타입을 지정하는 방법
// 타입이 달라서 에러 발생
// helloBasic<string>(39);
// 정상 출력
helloBasic<string, number>("message", 1);

타입을 추론하는 방법

// 타입이 추론되어진다.
helloBasic(36, 33);

 

배열 형태로 선언하는 방법

//제네릭 함수 배열 선언
function helloArray<T>(message: T[]): T {

  // T 배열의 0번째 -> T요소 자체가 리턴된다.
  return message[0];
}

 

배열 형태로 값 지정

// Type: string
helloArray(["Hello", "World"]);

// Type: String | number
helloArray(["Hello", 5]);

 

튜플 형태로 선언

function helloTuple<T, K>(message: [T, K]): T {
  
  return message[0];
}

 

튜플 형태로 값 지정

// type: String, string
helloTuple(["Hello", "World"]);
// type: string, number
helloTuple(["Hello", 5]);

 

타입선언 방식

type HelloFunctionGeneric1 = <T>(message: T) => T; 

const helloFunction1: HelloFunctionGeneric1 = <T>(message: T): T => {
  return message;
};

 

인터페이스 선언 방식

interface HelloFunctionGeneric2 {
  <T>(message: T): T;
}

const helloFunction2: HelloFunctionGeneric2 = <T>(message: T): T => {
  return message;
};

 

class에서 제네릭을 선언하고 사용하는 방법

// class 에서 제네릭을 사용하는 방법
class Person1111<T>{
  private _name: T;

  constructor(name: T){
    this._name = name;
  }
}

new Person1111("Mark");
new Person1111<string>("aaa");

 

제네릭에 extends를 사용하는 방법

T 타입에 제한을 걸어주는 방법이다.

// 제네릭에 extends를 사용하는 방법
// T에는 string 과 number만 사용 가능하다.
class PersonExtends<T extends string | number> {
  private _nmae: T;

  constructor(name: T){
    this._nmae = name;
  }
}

new PersonExtends("Marks");
new PersonExtends(222);

// 에러 발생
// new PersonExtends(true);

 

타입을 찾는 방법

keyof 를 이용하여 key값에 해당하는 데이터만 입력이 가능하도록 설정할 수 있다.

interface IPerson {
  name: string;
  age: number;
}

// keyof를 이용하면 객체의 key값으로 타입이 정해진다.
type Keys = keyof IPerson;
const keys1: Keys = "age";
const keys2: Keys = "name";

const person555533: IPerson = {
  name: "Mark",
  age: 33
};

// IPerson[keyof IPerson] => IPerson["name" | "age"] => IPerson["name"] | IPerson["age"] => string | number
function getProp(obj: IPerson, key: keyof IPerson): IPerson[keyof IPerson] {
  return obj[key];
}

function getProp2<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}
// name 혹은 age 만 입력 가능하다.
console.log(getProp2(person555533, "age"));
console.log(getProp2(person555533, "name"));

// 유니온 타입이기 때문에 에러 발생
// function setProp(obj: IPerson, key: keyof IPerson, value: string | number): void{
//   obj[key] = value;
// }

function setProp2<T, K extends keyof T>(obj: T, key: keyof T, value: T[K]): void{
  console.log(obj);
  obj[key] = value;
}
setProp2(person555533, "name", "A");
setProp2(person555533, "age", 22);

'프론트엔드 > TypeScript' 카테고리의 다른 글

Abstract Class  (0) 2021.06.21
Class - 상속  (0) 2021.06.21
class - singleton 패턴  (0) 2021.06.21
class - Static Properties 와 Method  (0) 2021.06.21
class - index Signatures  (0) 2021.06.21

Abstract: 완전하지 않은 클래스, new로 바로 선언하여 사용하지 못한다. 사용하기 위해서는 상속받은 다음에 기능을 완성시킨후 사용한다.

 

예제

TS파일

abstract class AbstractPerson {
  protected _name: string = 'Mark';

  // 내용을 구현하지 않는다.
  abstract setname(name: string):void;
}

// 기능이 완성되지 않았기 때문에 에러가 발생한다.
// const p66 = new AbstractPerson();

// 상속하여 사용
class Person66 extends AbstractPerson {
  
  setname(name: string): void {
    console.log(this._name);
    this._name = name;
    console.log(this._name);
  }

}

const p66 = new Person66();
p66.setname("입력 후");

 

컴파일된 JS 파일

"use strict";
class AbstractPerson {
    constructor() {
        this._name = 'Mark';
    }
}
// 기능이 완성되지 않았기 때문에 에러가 발생한다.
// const p66 = new AbstractPerson();
// 상속하여 사용
class Person66 extends AbstractPerson {
    setname(name) {
        console.log(this._name);
        this._name = name;
        console.log(this._name);
    }
}
const p66 = new Person66();
p66.setname("입력 후");

 

화면 확인

'프론트엔드 > TypeScript' 카테고리의 다른 글

제네릭  (0) 2021.06.22
Class - 상속  (0) 2021.06.21
class - singleton 패턴  (0) 2021.06.21
class - Static Properties 와 Method  (0) 2021.06.21
class - index Signatures  (0) 2021.06.21

클래스가 어떠한 다른 클래스의 기능을 가져다가 사용할 때 상속받아 사용한다.

 

private, protected 키워드를 이용해서 각자의 영역에서 서로의 영역을 오염시키지 않도록 조심하는것이 중요

 

예제

TS 파일

class Parent {
  constructor(protected _name: string, private _age: number){}

  public print(): void {
    console.log(`이름은 ${this._name} 이고, 나이는 ${this._age} 입니다.`);
  }

  protected printname(): void {
    console.log(this._name, this._age);
  }
}

const p331 = new Parent('Mark', 22);
p331.print();

// 상속
class Child extends Parent {

  public _name = "Mark jr";

  public gender = "male";

  constructor(age: number){
    // super를 최상단에 위치해야 부모의 것들을 접근 가능하다
    super('생성자 재정의', age);
    this.printname();
  }
}

// Child에 별다른 선언을 하지 않았을 경우에는 Parent 생성자를 그대로 사용한다.
// const c = new Child("Son", 4);
// CHild에서 재정의
const c = new Child(33);
c.print();
c.gender

컴파일된 JS 파일

"use strict";
class Parent {
    constructor(_name, _age) {
        this._name = _name;
        this._age = _age;
    }
    print() {
        console.log(`이름은 ${this._name} 이고, 나이는 ${this._age} 입니다.`);
    }
    printname() {
        console.log(this._name, this._age);
    }
}
const p331 = new Parent('Mark', 22);
p331.print();
// 상속
class Child extends Parent {
    constructor(age) {
        // super를 최상단에 위치해야 부모의 것들을 접근 가능하다
        super('생성자 재정의', age);
        this._name = "Mark jr";
        this.gender = "male";
        this.printname();
    }
}
// Child에 별다른 선언을 하지 않았을 경우에는 Parent 생성자를 그대로 사용한다.
// const c = new Child("Son", 4);
// CHild에서 재정의
const c = new Child(33);
c.print();
c.gender;

 

화면 확인

'프론트엔드 > TypeScript' 카테고리의 다른 글

제네릭  (0) 2021.06.22
Abstract Class  (0) 2021.06.21
class - singleton 패턴  (0) 2021.06.21
class - Static Properties 와 Method  (0) 2021.06.21
class - index Signatures  (0) 2021.06.21

사용자가 직접 접근이 불가능하고 Class를 통해서만 접근가능하도록 설계

 

예제

TS 파일

class ClassName {

  private static instance: ClassName | null = null;

  public static getInstance(): ClassName{
    
    // Classname으로 부터 만든 object가 없으면 만든다.
    if (ClassName.instance === null){
      // class 내부이기 때문에 호출 가능
      ClassName.instance = new ClassName();
    }
   // ClassName으로 부터 만든 object가 있으면 그걸 리턴
    return ClassName.instance;
  }
  // new로 생성하지 못하도록 한다.
  private constructor() { };

}

const a12 = ClassName.getInstance();
const b12 = ClassName.getInstance();

// 서로 같은지 비교
console.log(a12 === b12);

 

컴파일된 JS 파일

"use strict";
class ClassName {
    // new로 생성하지 못하도록 한다.
    constructor() { }
    static getInstance() {
        // Classname으로 부터 만든 object가 없으면 만든다.
        if (ClassName.instance === null) {
            // class 내부이기 때문에 호출 가능
            ClassName.instance = new ClassName();
        }
        // ClassName으로 부터 만든 object가 있으면 그걸 리턴
        return ClassName.instance;
    }
    ;
}
ClassName.instance = null;
const a12 = ClassName.getInstance();
const b12 = ClassName.getInstance();
// 서로 같은지 비교
console.log(a12 === b12);

 

결과 확인

'프론트엔드 > TypeScript' 카테고리의 다른 글

Abstract Class  (0) 2021.06.21
Class - 상속  (0) 2021.06.21
class - Static Properties 와 Method  (0) 2021.06.21
class - index Signatures  (0) 2021.06.21
class - readonly 속성  (0) 2021.06.21

static을 붙여서 클래스명을 직접적으로 선언하여 해당 메소드나 변수를 불러올 수 있다.

 

예제

TS 파일

class Person56 {

  public static CITY = "Seoul";

  public static hello(){
    console.log("안녕하세요", Person56.CITY, this.CITY);
  }

}

const p56 = new Person56();
// object에서 사용 불가능하다.
// p56.hello();
// p56.CITY = "aaa";

// 클래스에서 직접적으로 가져올 수 있다.
Person56.hello();
console.log(Person56.CITY);

컴파일된 JS 파일

"use strict";
class Person56 {
    static hello() {
        console.log("안녕하세요", Person56.CITY, this.CITY);
    }
}
Person56.CITY = "Seoul";
const p56 = new Person56();
// object에서 사용 불가능하다.
// p56.hello();
// p56.CITY = "aaa";
// 클래스에서 직접적으로 가져올 수 있다.
Person56.hello();
console.log(Person56.CITY);

 

화면 확인

 

'프론트엔드 > TypeScript' 카테고리의 다른 글

Class - 상속  (0) 2021.06.21
class - singleton 패턴  (0) 2021.06.21
class - index Signatures  (0) 2021.06.21
class - readonly 속성  (0) 2021.06.21
class - getter & setter  (0) 2021.06.21

index를 이용하여 변수명을 사용자가 원하는 값으로 넣어줄수 있다.

예제

TS 파일

// class => object
// {mark: 'male', jade: 'male'}
// {chloe: 'female', alex: 'male', anna: 'female'}

class Students {
  
  [index: string]: "male" | "female";
}

const a = new Students();
a.mark = "male";
a.jade = "male";
console.log(a);

const b = new Students();
b.cloe = "female";
b.alex = "male";
b.anna = "female";
console.log(b);

컴파일된 JS 파일

"use strict";
// class => object
// {mark: 'male', jade: 'male'}
// {chloe: 'female', alex: 'male', anna: 'female'}
class Students {
}
const a = new Students();
a.mark = "male";
a.jade = "male";
console.log(a);
const b = new Students();
b.cloe = "female";
b.alex = "male";
b.anna = "female";
console.log(b);

 

화면 확인

+ Recent posts