6 분 소요

1. Type Annotation

// 타입 에러
let a = "Amy";
a = 39;  // Error

// a의 타입을 string로 지정
let a: string;

a = "Amy";
a = 39;  // Error

// a의 타입을 number로 지정
let a: number;

a = "Amy";  // Error
a = 39;

// 함수 내의 type annotation
function hello(b: number) {
  
}
hello(39);
hello('Amy');  // Error


2. Typescript Types vs Javascript Types

  • Typescript : Static Types(개발 중간에 타입 체크)
  • Javascript : Dynamic Types(runtime에 들어가야 체크)
// Javascript

function add(n1, n2) {
  // runtime에서 에러 체크
  if (typeof n1 !== 'number' || typeof n2 !== 'number') {
    throw new Error('Incorrect input!');
  }
  return n1 + n2;
}

const result = add(10, 20);


// Typescript

// 개발중에 체크
function add(n1: number, n2: number) {
  return n1 + n2;
}

const result = add(10, 20);


  • Typescript에서 제공하는 데이터 타입
  • Javascript 기본 자료형 포함(superset)
    • ECMAScript 표준에 따른 기본 자료형(6가지)
    • Boolean
    • Number
    • String
    • Null
    • Undefined
    • Symbol(ECMAScript 6에 추가)
    • Array: object형
  • 프로그래밍을 도울 몇가지 타입 추가 제공
    • Any, Void, Never, Unknown
    • Enum
    • Tuple: object형


3. Primitive Types

  • 오브젝트와 레퍼런스 형태가 아닌 실제 값을 저장하는 자료형
  • Primitive 형의 내장 함수를 사용 가능한 것은 Javascript 처리 방식 덕분
  • Primitive types은 모두 소문자
  • ES2015 기준 6가지
    • boolean
    • number
    • string
    • symbol
    • null
    • undefined
  • literal 값으로 Primitive 타입의 서브 타입을 나타낼 수 있음
  • wrapper 객체로 만들 수 있음
// 내장함수 사용 가능
let name = 'Amy';
name.toString();

// literal 값으로 Primitive 타입의 서브 타입 표시
true;
'hello';
3.14;
null;
undefined;

// wrapper 객체(Typescript에서는 권장하지 않음)
new Boolean(false);  // typeof new Boolean(false) : 'object'
new String('world');  // typeof new String('world') : 'object'
new Number(29);  // typeof new Number(29) : 'object'


4. boolean

// boolean.ts

let isDone: boolean = false;
isDone = true;
console.log(typeof isDone)  // boolean
console.log(isDone);  // true

let isOk: Boolean = true;
isOk = false;
console.log(typeof isOk);  // boolean
console.log(isOk);  // false

let isNotOk: boolean = new Boolean(true);  // Error


$ nxp tsc
$ node boolean.js  # boolean


5. number

  • Javascript와 같이 Typescript의 모든 숫자는 부동 소수점 값
  • 10진수 및 16진수 외에도, ECMAScript 2015에 도입된 2진수 및 8진수 지원
  • NaN
  • 1_000_000과 같은 표기 가능
// number.ts

// 10진수 리터럴
let decimal: number = 7;

// 16진수 리터럴
let hex: number = 0xf00e;

// 2진수 리터럴
let binary: number = 0b1100;

// 8진수 리터럴
let octal: number = 0o732;

// NaN
let notANumber: number = NaN;

// 밑줄 표기
let underscoreNum: number = 1_000_000;


6. string

  • 텍스트 형식을 참조하기 위해 string 형식을 사용
  • 문자열 데이터를 둘러싸기 위해 큰 따옴표나 작은 따옴표를 사용
// string.ts

let myName: string = 'Lee';
myName = "LWW";


- Template String

  • 행에 걸쳐 있거나, 표현식을 넣을 수 있는 문자열
  • 이 문자열은 backtick 기호에 둘러쌓여 있음
  • 포함된 표현식은 `${expr}` 와 같은 형태로 사용
// template string 사용
let fullName: string = 'WW Lee';
let age: number = 29;
let sentence: string = `Hello, My name is ${fullName}.

I'll be ${age + 1} years old next month.`;

console.log(sentence);  // Hello, My name is WW Lee.

                        // I'll be 30 years old next month.

// template string을 사용하지 않을 경우
let sentence: string = "Hello, My name is " + fullName + ".\n\n" +
  "I'll be " + (age + 1) + " years old next month.";


$ nxp tsc
$ node string.js


7. Symbol

  • ECMAScript 2015에 추가
  • new Symbol로 사용할 수 없음
  • Symbol을 함수로 사용해서 symbol 타입을 만들 수 있음
  • Primitive type의 값을 담아서 사용
  • 고유하고 수정 불가능한 값으로 만들어 줌
  • 주로 접근을 제어하는데 쓰는 경우가 많음
// tsconfig.json

"lib": [
  "ES2015",
  "DOM"
]


// symbol.ts

console.log(Symbol('foo') === Symbol('foo'))  // false

const sym = Symbol();
const obj = {
  [sym]: "value",
};

obj["sym"];  // 접근 불가
obj[sym];


$ nxp tsc
$ node symbol.js


8. null & undefined

  • Typescript에서 null과 undefined는 실제로 각각 null과 undefined 타입을 가짐
  • void와 마찬가지로, 그 자체로는 그다지 유용하지 않음
  • 둘 다 소문자만 존재
  • 다른 모든 타입의 서브타입으로 존재
  • 컴파일 옵션에서 `–strictNullChecks` 사용하면, void나 자기 자신에만 할당 가능
    • 이 경우, null과 undefined를 할당할 수 있게 하려면, union type을 이용해야 함
// null.ts

let MyName: string = null;  // Error
let u: undefined = null;  // Error

let v: void = undefined;
let union: string | null = null;
union = "LWW";


- null in Javascript

  • null이라는 값으로 할당된 것
  • 무언가 있는데, 사용할 준비가 덜 된 상태
  • null 타입은 null 값만 가질 수 있음
  • 런타임에서 typeof 연산자를 이용해 알아내면, object

- undefined in Javascript

  • 값을 할당하지 않은 변수는 undefined 값을 가짐
  • 무언가가 아예 준비가 안된 상태
  • object의 property가 없을 때도 undefined
  • 런타임에서 typeof 연산자를 이용해 알아내면, undefined


9. object

  • Primitive type이 아닌 것을 나타내고 싶을 때 사용하는 타입
  • Primitive type이 아닌것
    • number, string, boolean, bigint, symbol, null, undefined가 아닌 것
// object.ts

// person1은 object 타입이 아님
// person1은 {name: string, age: number} 타입
const person1 = {
  name: 'LWW',
  age: 29
};

// object 타입
const person2 = Object.create({
  name: 'LWW',
  age: 29
});

let obj: object = {};
obj = {name: 'LWW'};
obj = [{name: 'LWW'}];
obj = 29;  // Error
obj = 'LWW';  // Error
obj = true;  // Error
obj = 100n;  // Error
obj = Symbol();  // Error
obj = null;  // Error
obj = undefined  // Error

declare function create(o: object | null): void;
create({prop: 0});
create(null);
create(42);  // Error
create("string");  // Error
create(false);  // Error
create(undefined);  // Error

Object.create(0);  // Error


10. Array

  • 원래 Javascript에서 array는 객체
  • 사용방법
    • Array<타입>
    • 타입[]
// array.ts

// 방법 1(선호)
let list1: number[] = [1, 2, 3];

// 방법 2
let list2: Array<number> = [4, 5, 6];

// 여러 타입
let list3: (number | string)[] = [7, 8, 9, "0"];


11. Tuple

// tuple.ts

let x: [string, number];

x = ['hello', 29];
x = [10, 'world']  // Error
x[3] = 'item';  // Error

const person: [string, number] = ["LWW", 29];

// const first: string, const second: number
const [first, second] = person;


12. any

  • 어떤 타입이어도 상관없는 타입
  • any를 써야하는데 쓰지 않으면 오류를 뱉는 컴파일 옵션 nolmplicitAny가 있음
  • any는 계속해서 개체를 통해 전파됨
  • 모든 편의는 타입 안전성을 잃는 대가로 오는 것
  • 타입 안전성은 Typescript를 사용하는 주요 동기
  • 최대한 쓰지 않는 것을 권장
  • 컴파일 타임에 타입 체크가 정상적으로 이루어지지 않을 수 있음
// any.ts

function returnAny(message: any): any {
  console.log(message);
}

const any1 = returnAny('리턴은 아무거나');
any1.toString();

// 전파를 통해 안전성을 잃음
let losselyTyped: any = {};
const d = losselyTyped.a.b.c.d;

// any 누수 막는 법
function leakingAny(obj: any) {
  // 타입을 지정
  const a: number = obj.num;  // const a: number
  const b = a + 1;  // const b: number
  return b;
}

const c = leakingAny({ num: 0 });  // const c: number
c.indexOf("0");


13. unknown

  • 응용 프로그램을 작성할 때 모르는 변수의 타입을 묘사해야 할 수 있음
  • 이러한 값은 동적 콘텐츠의 모든 값을 의도적으로 수락하기를 원할 수 있음
  • 컴파일러와 사람에게 이 변수가 무엇이든 될 수 있음을 알려주는 unknwon 타입을 제공
  • any와 짝으로 any보다 Type-safe한 타입
    • any와 같이 아무거나 할당 가능
    • 컴파일러가 타입을 추론할 수 있게끔 타입의 유형을 좁힘
    • 타입을 확정해주지 않으면 다른 곳에 할당할 수 없고, 사용 불가
  • unknown 타입을 사용하면, runtime error를 줄일 수 있음
  • 사용 전에 데이터의 일부 유형의 검사를 수행하야 함을 알리는 API에 사용 가능
// unknown.ts

declare const maybe: unknown;
const aNumber: number = maybe;  // Error

if (maybe === true) {
  const aBoolean: boolean = maybe;  // const maybe: true
  const aString: string = maybe;  // Error
}

if (typeof maybe === 'string') {
  const aString: string = maybe;  // const maybe: string
  const aBoolean: boolean = maybe;  // Error
}


14. never

  • never 타입은 모든 타입의 서브타입이며, 모든 타입에 할당 할 수 있음
  • never에는 어떤 것도 할당할 수 없음
  • any조차도 never에 할당할 수 없음
  • 잘못된 타입을 넣는 실수를 막고자 할 때 사용
// never.ts

function error(message: string): never {
  throw new Error(message);
}

function fail() {
  return error('failed');
}

function infiniteLoop(): never {
  while (true) { }
}

let a: string = 'hello';
if (typeof a !== 'string') {
  a;  // let a: never
}

declare const b: string | number;
if (typeof b !== "string") {
  b;  // const b: number
}

type Indexable<T> = T extends string ? T & { [index: string]: any } : never;
type ObjectIndexable = Indexable<{}>;

const b: Indexable<{}> = '';  // Error


15. void

  • 리턴값으로 무엇도 하지 않음을 명시적으로 표현
function returnVoid(message: string): void {
  console.log(message);
  return undefined;
}

const r = returnVoid('리턴이 없음.');  // const r: void

댓글남기기