Into the Typescript 1

wook2·2021년 3월 10일
2

typescript

목록 보기
1/4
post-thumbnail

타입스크립트란?

자바스크립트의 정적 타입 검사자이다.


타입스크립트가 나오게 된 계기

  • 자바스크립트는 동적 프로그래밍 언어이다.
    C#, Java등 강한 타입을 적용하는 프로그래밍 언어는 컴파일 과정을 거친뒤, 실행하게 된다. 이 컴파일 과정에서 문법적인 오류등을 미리 확인할 수 있어 잘못된 부분을 빠르게 진단하여 수정할 수 있다.
    하지만 자바스크립트는 이러한 과정을 거치지 않고, 바로 런타임 환경에서 실행되기 때문에 문법적인 오류가 많이 발생하는데, 타입스크립트라는 강한 타입 시스템을 적용해 런타임에서 나오는 에러들의 상당부분을 줄일 수 있다.

타입이 가지는 장점

- 에러의 사전 방지

정수형 10과 문자열 20을 더할때, 서로 형이 맞지 않기 때문에, 올바르지 않은 연산이다. 문맥상 올바르지 않은 연산이지만 자바스크립트에서는 문자열 '1020' 을 결과로 나타낸다. 이것이 후에 다른 함수의 매개변수나, 변수에 할당된다고 상상해보자. 처음에는 쉽게 알아차리겠지만, 깊이가 점차 깊어지게되면 이런 사소한 에러를 찾는데에 많은 시간을 쏟을 것이다.

- 코드 미리보기 가능

위의 사진은 JsDoc을 이용해 typedef에 따른 property를 선언하고, 그에따라 어떤 변수가 올수 있는지 미리 볼수 있다.
만일 api로 받아온 객체 내부를 확인하려면 기존의 방법은 console.log를 찍어보고 실행시켜 확인하는 방법일 것이다. 그런데 객체 내부의 변수의 길이가 길고, 변수이름에 대소문자가 섞여있다면 변수이름을 잘못치는 경우가 많을것이고 이것 또한 잠재적 에러를 만들어내는 주범이 된다. 그렇기 때문에 미리 변수를 보고 사용한다면 잠재적인 에러를 줄일 수 있다.


TS 시작하기

  • typescript 설치하기
    npm을 이용하여 typescript를 설치한다. 설치 후, ts파일을 만들고 js파일로 컴파일하기 위해서는 tsc명령어를 사용하면 된다.
    tsc index.ts 를 하게되면 index.js로 컴파일하게 된다.
  • tsconfig
    tsconfig파일을 통해 여러가지 옵션들을 설정할 수 있다.
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,
    "noImplicitAny": false
  },
  "include": ["./src/**/*"]
}

TS 기본타입

타입을 지정하기 위해서는 어떤 타입이 있는지를 알아보아야 한다. 타입의 종류에는 12가지가 있다.

  • Boolean
  • Number
  • String
  • Object
  • Array
  • Tuple
  • Enum
  • Any
  • Void
  • Null
  • Undefined
  • Never

기본타입) 문자열, 숫자, 배열, 튜플, 객체, 진위값

  • 문자열
const str: string = 'hello';

위와 같이 annotation을 이용해 사용한다.

  • 숫자
const num: number = 10;
  • 배열
const arr: Array<string> = [];
arr.push('hi');

const items: string[] = [];

배열은 형을 명시하여 Array < string > 으로 표현하거나, 리터럴로도 쓸 수 있다.

  • 튜플
const address: [string, number] = ['seoul', 40];

튜플은 배열의 각 원소마다에 형을 지정해줄 수 있다.

  • 객체
const obj: object = {};
const person: { age: number; name: string } = { age: 100, name: 'Capt' };
person.age = 101;

객체는 object로 형을 지정해줄 수 있고, 객체 안의 원소또한 형을 지정해줄 수 있다.

  • 진위값
let isLoggedIn: boolean = false;

isLoggedIn에는 True 와 False같이 진위값만 할당할 수 있다.

함수타입

함수를 선언하는 경우 매개변수와 반환값의 형을 지정해줄 수 있다.

function add(a: number, b: number): number {
  return a + b;
}

또한 함수의 인자가 더 많이 들어오는 경우는 에러를 발생시키며, 이는 옵셔널 파라미터를 이용해 해결할 수 있다.

function printText(text: string, type?: string) {
  console.log(text);
}

printText라는 함수의 두번째 인자인 type에 ?를 붙여서 인자가 들어와도 되고, 안들어와도 되는경우 모두를 포함한다.

void, any 타입

void 타입은 함수에서 리턴값이 없을때 void를 쓸 수 있다.

any 타입은 말 그대로 어떤 타입이든 가능하다는 뜻이다. any를 쓰게되면 강력한 형 검사를 할수 없는 단점이 있다.


실습해보기

Todo라는 자료형을 배열의 원소로 가지는 todoItems 배열을 선언하였다.

let todoItems : Todo[];

todolist의 함수들의 매개변수와 반환값에 형을 지정해 주었다.

function completeTodo(index : number, todo : Todo) :void {
  todo.done = true;
  todoItems.splice(index, 1, todo);
}

인터페이스를 통해서 Todo타입을 지정하여, 코드 중복을 제거할 수 있었다.

interface Todo{
  id : number,
  title : string,
  done : boolean
}

인터페이스

  • 인터페이스란?
    인터페이스는 일반적인 정의로는 서로다른 두 시스템이 맞다는 경계면이다. 정보를 서로 주고받는데 사용된다.

    타입스크립트에서 인터페이스는 일반적으로 타입체크를 위해 사용된다. 인터페이스에 선언된 프로퍼티 , 메소드의 구현을 강제하여 타입이 일관성을 가지도록 하는 것이다.

  • 변수와 인터페이스
    인터페이스는 변수의 타입으로 사용될 수 있다. 위의 실습에서 함수의 매개변수로 인터페이스를 이용하였다. 함수 내부에서는 인터페이스의 규칙을 따라야 한다. 만일 인자로 받은 객체가 복잡하다면, 매개변수를 체크할 필요가 없다.

interface User{
    age : number,
    name : string
}

var wook : User = {
    age: 24,
    name: 'wook'
}
  • 함수와 인터페이스
    함수의 타입을 인터페이스로 정의할 수 있다. 인터페이스는 매개변수와 리턴타입을 정의한다.
interface sumFunction {
    (a : number, b:number) : number; 
}
var sumf : sumFunction;
sumf = function (a : number, b: number) : number{
    return a+b;
}
  • 인덱싱과 인터페이스
    배열의 인덱싱 타입을 지정할 수 있다. 아래의 인터페이스는 숫자를 인덱스로 받고 string값을 받는 인터페이스이다.
interface StringArray {
    [index : number] : string;
}
var k : StringArray  = ['a','b','c'];
k[0] = 'abc'
  • 딕셔너리 인터페이스
    객체 또한 타입을 지정할 수 있다. 아래의 인터페이스는 문자열을 key로 받고 문자열을 값으로 받는 인터페이스이다.
interface nameDictionary {
    [key : string] : string;
}
  • 인터페이스 상속
    인터페이스를 상속하여, 중복을 제거할 수 있다. extends를 사용하여 상속할 수 있다.
    아래의 예시의 Developer로 정의된 객체는 name, age, language를 모두 가져야하며, 형또한 일치해야 한다.
interface Person {
    name : string;
    age : number;
}

interface Developer extends Person {
    language : string;
}
  • readonly
    배열 요소를 변경하지 못하게 하기 위해서는 readonly를 사용할 수 있다.
interface ReadonlyArr{
    readonly [index: number] : string;
  }
  
  const arr : ReadonlyArr = ['wook','bin'];
  arr[2] = 'wang'


타입별칭 type

type은 어떤 타입에 이름을 부여하기 위해 존재한다. interface와 비슷한 방식으로 작동하는데, interface는 어떤 타입의 정의를 선언하는 것이고, type은 이미 정의된 타입에 이름을 붙이는것 뿐이다.
그렇기 때문에 type은 확장 불가능하고, interface는 확장가능하다. 만일 타입을 정의한다면 interface를 쓰는것이 바람직하다.

type Person = {
    name : string;
    age: number;
}

연산자를 이용한 타입 정의

  • 유니온을 이용한 타입정의
    union은 하나의 변수에 여러 타입을 적용할 수 있습니다. | 를 이용합니다. 아래의 사진은 객체에 유니온을 타입을 적용하였을 때 입니다.
    타입가드를 적용하지 않으면 lint는 공통된 속성인 name만 미리보기를 제공합니다.

  • 인터섹션을 이용한 타입정의

    인터섹션은 여러개의 타입을 합칠때 사용합니다. &를 이용합니다. 아래의 사진은 객체에 인터섹션을 적용하였을 때 입니다.
    lint는 someone은 두 객체의 합집합 속성에 대한 미리보기를 제공합니다.

  • 유니온과 인터섹션의 차이
    객체타입 A와 B가 있다고 가정하고 매개변수로 인자를 받아와 함수를 실행시키는 경우에,
    유니온은 타입A 또는 타입B 만 사용할 수 있습니다.
    반면, 인터섹션을 사용하는 경우 타입 A와 타입B의 속성 모두를 인자로 가져야 합니다.

profile
꾸준히 공부하자

2개의 댓글

comment-user-thumbnail
2021년 3월 13일

퀄리티가 상당하네요...! 🤩

1개의 답글