Typescript Basic Type

jiho·2019년 12월 28일
0

Typescript

목록 보기
3/3

이전 포스트에서 타입스크립트를 왜 사용해야하는지에 대해 길게 책 내용을 해석해봤습니다.

결국 정리해보자면 런타임 도중 오류를 발생할 가능성이 있는 타입변환을 정적타입을 도입함으로써 보완해줍니다. 그리고 기존의 자바스크립트에서 구현이 까다로웠던객체지향프로그래밍을 하기 쉽게 적용할 수 있게 해주는 문법들이 추가되었습니다.
(이 부분은 모던 자바스크립트들의 특징이지만 타입스크립트을 통해서도 누릴 수있는 이점입니다.)

타입스크립트를 제대로 시작해보겠습니다. eBook 내용을 기반으로 작성해보겠습니다.

Basic Type

기존 자바스크립트는 함수를 정의할 때, 인자에 어떤 타입의 값이라도 들어갈 수 있습니다.

Type syntax

function doCalculation(
	a : number,
    b : number,
    c : number) {
      return (a * b) + c
}

위는 doCaulation함수가 3개의 number 타입의 인자가 필요하다고 정의한 것입니다.
만약 number타입이 아니거나 인자의 개수가 3개가 아니라면 Error가 발생합니다.

책에서는 string, boolean, number 이 타입들에 각각 맞지않는 타입을 넣었을 때 에러가 발생한다는 내용을 길게 적어놓았습니다. 하지만 이 부분은 프로그래머라면 충분히 다 예상할 수 있기 때문에 생략하고 넘어가겠습니다.

타입 스크립트에 사용되는 몇가지 기술을 소개하겠습니다.

Inferred typing (암시된 타입)

타입 스크립트는 변수의 nature을 결정하기위해 inferred typing이라고 불리는 기술을 사용합니다.

var inferredString = "this is a string";
var inferredNumber = 1;

inferredString = inferredNumber;

위와 같이 코드를 작성하고 실행해보면 아마 에러가 발생할 것입니다. 이것이 inferred typing입니다. 타입을 명시하지않아도 맨 처음 할당할 때 해당 변수의 타입이 결정됩니다.

Duck typing

duck pattern 과같이 duck이 많이 나오는데 이 단어의 의미를 저는 여기서 처음알았습니다.

만약 그것이 오리같이 생기고 오리같이 걸으면 아마 그것은 오리일 것입니다.

이 말의 뜻은 만약 두 개의 변수를 비교할 때, 그것들이 같은 properties와 methods를 가지고 있다면, 그것들은 서로 교체(?)될 수 있다는 것을 의미합니다.

var complexType = { name: "myName", id: 1};
complexType = {name: " anothoerName", id: 2};

즉 위와 같이 타입스크립트는 같은 property를 가지는 객체는 같은 타입으로 판단하는 것을 의미합니다. 만일 하나의 프로퍼티라도 타입이 다른거나 없다면 에러를 발생시킬 것입니다.

위에서 소개한 duck typing과 inferred typing은 타입스크립트 언어의 강력한 기능입니다.

Template string

이 부분은 ES6에서 도입된 것을 타입스크립트도 사용한다는 내요이니 생략하겠습니다.

console.log(`this is ${testVariable}`);

다음과 같이 포맷팅을 사용할 수 있는 기능입니다. 디버깅할 때 도움이 많이 될 것 같네요.

Array type

자바스크립트의 기본타입(string, number, boolean) 이외에도 자바스크립트는 다른 두개의 basic data type을 가지고 있습니다. arrays와 enums입니다.

var arrayOfNumbers: number [] = [1,2,3];

위와 같이 []을 사용해서 number array타입을 선언할 수 있습니다. 추후에 나오겠지만 pipe line |을 이용해서 string | number [] string과 number 두개의 타입을 담을 수 있는 배열 타입도 만들 수 있습니다.

배열얘기가 나와서 배열을 사용하는 방법을 몇가지 남기겠습니다. ES6 내용입니다.

for ... in

위 문법을 사용하면 배열의 요소를 순서대로 loop할 때 용이합니다.

for (var itemKey in arrayOfStrings) {
  var itemValue = arrayOfStrings[itemKey];
  console.log(`arrayOfStrings[${itemKey}] : ${itemValue}`);

위와 같이 인덱스를 가져올 수 있고

for ... of

위 문법을 사용하면 배열내의 요소를 바로 가져올 수 있습니다.

for (var itemValue of arrayOfStrings) {
  console.log(`arrayItem : ${itemValue}`);

any type

타입스크립트를 사용할 때, any라는 타입을 표시해주면 해당 변수에 어떠한 타입도 넣을 수 있습니다.

Simply Find an Interface for the Any Type(S.F.I.A.Y)

짧게말해 최대한 any type 을 사용하는 것을 피하라고 합니다.

Explicit casting

명시적인 타입 캐스팅도 존재합니다.

var item1 = <any> {id: 1, name:"item 1"};
item1 = { id: 2 };

사용법은 위와 같습니다.

Enums

OOP 언어들은 항상 Enum타입을 가지고 있습니다. Java, C++, C#
그래서 타입스크립트도 basic type으로 가지고 있습니다.

enum DoorState {
  	Open,	
      Close,	
      Ajar
}
var colorOpenDoor = DoorState.Open;
var colorDoor = DoorState['Close'];

사용법은 객체를 다룰 때와 똑같습니다.

Definite assignment

타입 스크립트는 할당되지않은 변수를 사용하는 것을 금지합니다. 하지만 나중에 할당되어야할 경우도 가끔존재합니다. 호이스팅을 이용할 때가 그렇습니다.

let globalString: string;
setGlobalString();
console.log(`globalString: ${globalString}`);
function setGlobalString() {
  globalString = "this is the string";
}

만약 실행하면 console.log를 호출할 때는 아마 globalString은 undefined이 아니지만 타입스크립트는 globalString은 할당이 되지않았다고 판단하게됩니다. 해결책은globalString변수에 exclamation mark(!) 를 사용하는 것입니다.

let globalString!: string;

이 표시는 컴파일러에게 이 변수는 값을 할당하기전에 사용해도 에러를 발생하지 말라고 말하는 것과 같습니다. 사용할 때 해당 표시를 해도 동일합니다.

console.log(`globalString: ${globalString!}`);

Functions

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

함수는 위와같이 타입을 정의합니다. 괄호 뒤의 :number는 리턴값을 의미합니다.

Optional parameters

function concateStrings(a: string, b: string, c?:string){
  return a+b+c
}

만약 위와 같이 인자에 c?:string을 정의하면 3번째 인자를 할당하지않아도 에러를 발생하지 않겠죠.(대신 결과에는 undefined 가 붙을 것입니다.)
a, b인자는 반드시 주어져야합니다.

Default parameters

function concateStringDefault(
	a: string,
     b:string,
     c:string="c"){
      return a+b+c;
}

위와 같이 default parameter를 설정해서 optional parameter를 나타낼 수 있습니다.

Rest parameters

만약 parameter의 개수가 고정적이지 않을 경우, 아래와 같이 할 수 있습니다.

function testArgumets(...argArray: number []){
  if(argArray.length > 0){
    for (var i = 0; i < argArray.length; i++){
      console.log(argArray[i]);
    }
  }
}

Function callbacks

함수형 프로그래밍에서는 함수를 인자로 넘기는 일이 많죠. 그래서 function 의 타입도 지정해줄 수 있습니다.

function doSomethingWithCallback(
	initialText: string,
     callback: (initialText: string) => void
    ){
      console.log("hello");
      callback(initialText);

위와 같이 콜백함수의 인자와 return 타입을 정해줄 수 있습니다. 이 기능은 매우 강력할 것 같습니다.

Function overrides

가끔은 하나의 함수가 여러 타입을 연산하기 원할 때도 있습니다. 자바나 C++에서는 함수 Override를 통해 같은함수가 다른 타입의 연산을 지원해줄 수 있습니다. 타입스크립트도 가능합니다.

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

위와 같이 override를 사용할 수도 있습니다. 대신 정의하지않은 타입인 boolean값을 넣을시 에러가 발생합니다.

Advanced Types

조금 고급 타입들을 보겠습니다.

Union types

union type은 두개 이상의 다른 타입의 조합으로 type을 표현할 수 있습니다.

var unionType : string | number;
unionType = 1;
unionType = "test";

다음과 같이 pipe symbol(|)를 사용하면 여러 타입을 조합할 수 있습니다.

Type aliase

우리가 생성한 타입에 별칭을 부여함으로써 프로그래밍의 가독성을 올릴 수 있습니다. 앞서 소개한 union type과 함께 사용하면 효과적일 것 같습니다.

type StringOrNumber = string | number;
function addWithAlias(
	arg1: StringOrNumber,
    arg2: StringOrNumber,
     ): string {
      return arg1.toString() + arg2.toString();
}

위와 같이 string과 number 타입을 동시에 허용하는 타입을 type 을 통해 정의할 수 있습니다. C언어에서 #define을 통해 매크로를 정의하는 것과 비슷하네요.

물론 함수의 타입로 미리 정의할 수 있습니다.

type CallbackWithString =(string) => void;

Null and undefined

자바스크립트에서 변수값이 할당되있지않으면 undefine를 돌려줍니다. 하지만 null이라는 값도 가지고 있는데 차이는 아래와 같습니다.
null는 변수가 어디있는지 알지만 값을 가지고 있지않을 때, undefined는 현재 스코프에서 어디에도 정의되있지않을 때 사용됩니다.
타입스크립트의 타입에도 null과 undefined가 있습니다.

아마 null을 허용할 때 union타입으로 사용할 것같습니다.

function testUndef(test: null | number){
  	console.log("test parameter: " + test);
}

Tuple

마지막으로 Tuple 타입에 관해 알아보겠습니다.
저는 파이썬을 사용하다가 js로 넘어와서 튜플이 크게 낯설지않습니다. Tuple은 사물의 유한한 순서를 뜻합니다.

let tupleType: [string, boolean];
tupleType = ["test", false];

튜플의 타입정의는 위와같이 square bracket으로 타입을 정의해주면 됩니다.
사용할 때는 아래와같이 사용하거나 배열처럼 사용하면 될 것같습니다.

let [e1, e2] = tupleType;

rest syntax

function useTupleAsRest(...args: [number, string, boolean]){
  let [arg1, arg2, arg3] = args;
  ...
}

다음과 같이 rest 인자들의 타입을 튜플로 정해줄 수 있고

type RestTupleType = [number, ...string[]];
let restTuple: RestTupleType = [1, "string1", "string2", "string3"]

type alias를 통해 rest인자를 받을 수 도 있습니다.

마무리

모든 타입에 관해서 모두 나열하지않았지만 기본적이 타입들에 대해서는 다본것같습니다.
BigInt라는 것도 있고 응용하면 여러 방법이 있겠지만 그건 그 때마다 공부해야할 것 같네요.

profile
Scratch, Under the hood, Initial version analysis

0개의 댓글