본문 바로가기

JavaScript

타입스크립트 기초문법2

728x90

타입스크립트 기초문법2


📌 초기 설정

npm init -y
npm i typescript @types/node ts-node -D
tsc --init

 

📄 tsconfig.json

{
    // 암시적 any 타입을 허용하지 않는다.
    "noImplicitAny": true
}

함수

function sum(a, b) {
    return a + b;
  }

아무런 타입을 지정해주지 않으면, any타입으로 인식.

오류 발생하지 않으나, any타입은 지양해야 함.

 

// any type 오류를 나게 하자
// tsconfig.json => "noImplicitAny": true
function sum(a: number, b: number): number {
    return a + b;
  }

 

📌 함수의 인자

function sum(a: number, b: number): number {
    return a + b;
    
  }
  sum(10, 20); // 30
  sum(10, 20, 30); // error, too many parameters
  sum(10); // error, too few parameters

함수의 인자는 필수값으로 간주


null값 허용

📄 tsconfig.json

{
	"strictNullChecks": false,
}

 

📌 인자에 ?를 붙여 null값을 허용해준다.

function sum(a: number, b?: number): number {
    return a + b;
    
  }
  sum(10, 20); // 30
  sum(10); // NaN

 

📌 인자 초기값 설정

function sum(a: number, b = 100): number {
  return a + b;
}
const result1 = sum(10, undefined); // 110
const result2 = sum(10, 20, 30); // error, too many parameters
const result3 = sum(10); // 110

console.log({ result1, result3 });

 

📌 This

interface Node {
  count: number;
  init(this: Node): () => {};
}

let nd: Node = {
  count: 10,
  init: function (this: Node) {
    return () => {
      return this.count;
    };
  },
};

let getCount = nd.init();
let count = getCount();

console.log(count); // 10

Literal

String⊃Literal

 

📌 문자 리터럴

// @errors: 2345
type Easing = "ease-in" | "ease-out" | "ease-in-out";

class UIElement {
  animate(dx: number, dy: number, easing: Easing) {
    if (easing === "ease-in") {
      // ...
    } else if (easing === "ease-out") {
    } else if (easing === "ease-in-out") {
    } else {
      // 하지만 누군가가 타입을 무시하게 된다면
      // 이곳에 도달하게 될 수 있습니다.
    }
  }
}

let button = new UIElement();
button.animate(0, 0, "ease-in");
button.animate(0, 0, "uneasy"); // type선언값에 없는 uneasy타입은 에러 발생

 

📌 숫자 리터럴

function rollDice(): 1 | 2 | 3 | 4 | 5 | 6 {
    return (Math.floor(Math.random() * 6) + 1) as 1 | 2 | 3 | 4 | 5 | 6;
  }
  
  const result4 = rollDice();

  console.log(result4);

1~6까지 랜덤한 숫자를 반환한다.

 


Union

function printId(id: number | string) {
    console.log(id.toUpperCase());
    // string | number' 형식에 'toUpperCase' 속성이 없습니다.
    // 'number' 형식에 'toUpperCase' 속성이 없습니다.
  }

id가 숫자 아니면 문자열인데, toUpperCase는 문자열에만 해당하므로 오류가 발생한다.

function printId(id: number | string) {
    // type narrowing
    if(typeof id === "string"){
      console.log(id.toUpperCase());
    }
  }

따라서 id값이 문자열일 때만, 대문자로 전환해주는 걸 명시해줘야 에러가 발생하지 않는다.

 


Intersection

type Common = {
  name: string,
  age: number,
  gender: string
}

type Animal = {
  howl: string
}

type Cat = Common & Animal;
type Dog = Common | Animal;

let dog: Dog = {
  howl: 'dogggg'
}
let cat: Cat = {
  age: 3,
  gender: 'C',
  name: 'CC',
  howl: 'cattttt'
}
결합(Intersection)
| 조합(Union)

 Type 과 Interface

type Common2 = {
    name: string,
    age: number,
    gender: string
  }
  
  type Animal2 = {
    howl: string
  }
  
  type Cat2 = Common2 & Animal2;
  type Dog2 = Common2 | Animal2;
  
  let dog2: Dog2 = {
    howl: 'dogggg'
  }
  let cat2: Cat2 = {
    age: 3,
    gender: 'C',
    name: 'CC',
    howl: 'cattttt'
  }
  Type Interface
확장 특수문자 &
리터럴 타입 확장 가능
extends(상속)
객체만 확장 가능
합성(merge) 재귀적으로 순회하면서 속성을 merge하기 때문에 제대로 merge되지 않을 수 있음 객체만 단순히 merge하기 때문에 충돌 거의 없음

class

 

📌 readonly

class Developer {
    readonly name: string;
  
    constructor(theName: string) {
      this.name = theName;
    }
  }
  
  let john = new Developer("John");
  john.name = "John"; // error! name is readonly.

 

 

📌 Accessor

class Developer {
    private _name: string;
  
    get name(): string {
      return this._name;
    }
  
    set name(newValue: string) {
      if (newValue && newValue.length > 5) {
        throw new Error("이름이 너무 깁니다");
      }
      this._name = newValue;
    }
  }
  
  const josh = new Developer();
  josh.name = "Josh";
  josh._name = "Josh"; // private이라 class외부에서는 접근 불가능
  console.log(josh.name); //Josh
  
  export { Developer };

 

 

📌 Abstract Class

인터페이스와 비슷한 역할을 하면서도 조금 다른 특성을 가지고 있음

특정 클래스의 상속 대상이 되는 클래스이며 좀 더 상위 레벨에서 속성, 메서드의 모양을 정의함.

abstract class Developer {
    abstract coding(): void; // 'abstract'가 붙으면 상속 받은 클래스에서 무조건 구현해야 함
    drink(): void {
      console.log("drink sth");
    }
  }
  
  class FrontEndDeveloper extends Developer {
    coding(): void {
      // Developer 클래스를 상속 받은 클래스에서 무조건 정의해야 하는 메서드
      console.log("develop front");
    }
    design(): void {
      console.log("design front");
    }
  }
  
  class BackEndDeveloper extends Developer {
    coding(): void {
      // Developer 클래스를 상속 받은 클래스에서 무조건 정의해야 하는 메서드
      console.log("develop server");
    }
    design(): void {
      console.log("design server");
    }
  }
  
  // const dev = new Developer(); // error: cannot create an instance of an abstract class
  const josh = new BackEndDeveloper();
  const kai = new FrontEndDeveloper();
  
  josh.coding(); // develop server
  josh.drink(); // drink sth
  josh.design(); // design server
  
  console.log("");
  
  kai.coding(); // develop front
  kai.drink(); // drink sth
  kai.design(); // design front
  
  export { Developer };

'JavaScript' 카테고리의 다른 글

TS, 내가 만든 포켓몬 크롤링 프로그램  (0) 2023.01.19
후발대_node.js 숙력주차 과제 복습  (0) 2023.01.19
타입스크립트 기초문법1  (0) 2023.01.17
TypeScript란?  (0) 2023.01.16
javascript 구조 분해 할당  (0) 2023.01.16