Basic Types

100pearlcent·2021년 8월 24일
0

TypeScript

목록 보기
1/6
post-thumbnail

TypeScript Types vs JavaScript Types

Static Types (set during development) vs Dynamic Types (resolved at runtime)

// JavaScript는
// 런타임 상에서 자료형을 체크를 해야하지만
function add(n1, n2) {
	if(typeof n1 !== 'number' || typeof n2 !== 'number') {
    	throw new Error('Incorrect input');
    }
  return n1 + n2;
}

// TypeScript는
// 타입 어노테이션을 통해 지정을 해준다
function add(n1: number, n2: number) {
	return n1 + n2;
}

TypeScript에서 제공하는 데이터타입

JavaScript 기본 자료형을 포함(superset)

  • Boolean
  • Number
  • String
  • Null
  • Undefined
  • Symbol (ECMAScript 6에 추가)
  • Array: object형

프로그래밍을 도울 몇가지 타입이 더 제공된다

  • Any, Void, Never, Unknown
  • Enum
  • Tuple : object형

Primitive Types

  • 오브젝트와 레퍼런스 형태가 아닌 실제 값을 저장하는 자료형
  • Primitive형의 내장 함수를 사용할 수 있는것은 자바스크립트 처리 방식 덕분
  • ES2015 기준 총 6가지 (boolean, number, string , symbol, null, undefined)
  • literal 값으로 Primitive 타입의 서브 타입을 나타낼 수 있다

👉 TypeScript의 핵심 Primitive types은 모두 소문자

Number / number

  • JavaScript와 같이 TypeScript의 모든 숫자는 부동 소수점 값
  • TypeScript는 16진수 및 10진수 리터럴 외에도, ECMAScript 2015에 도입된 2진수와 8진수를 지원
  • NaN
  • 1_000_000 과 같은 표기도 가능

String

Template String

  • 행에 걸쳐있거나, 표현식을 넣을 수 있는 백틱으로 둘러쌓인 문자열
let fullName: string = 'Jinju Baek';
let age: number = 26;

let sentence: string = `Hi, this is ${ fullName }
I'll be ${ age + 1 } years old next year.`;

Symbol

  • ECMAScript 2015에 새로 추가됨
  • new Symbol로 사용 불가능
  • Symbol을 함수로 사용해서 symbol 타입을 만들어 낼 수 있음
console.log(Symbol('foo') === Symbol('foo')); // false

언제 사용하는가?

  • Primitive Type의 값을 담아서 사용한다
  • 고유하고 수정불가능한 값으로 만들어준다

👉 주로 접근 제어시 쓰는 경우가 많다

const sym = Symbol();

const obj = {
	[sym]: "val"
};

console.log(obj[sym]) // "val"

Null & Undefined

  • TypeScript에서 undefined와 null은 실제로 각각 undefined 와 null이라는 타입을 가진다
  • void와 마찬가지고 그 자체로 그다지 유용하지는 않다
  • 타입과 값 둘 다 소문자만 존재한다
// 이 변수들에 할당할 수 있는 것들은 거의 없다

let u: undefined = undefined;
let n: null = null;
  • ts config파일 설정을 하지 않으면 그렇다
  • number에 null 또는 undefined를 할당할 수 있다는 의미
  • 하지만 컴파일 옵션에서 '--strictNullChecks'를 사용하면, null 과 undefined는 void나 자기 자신들에게만 할당할 수 있다 > 이 경우 null과 undefined를 할당할 수 있게 하려면, union type을 이용해야한다
let u: undefined = null; // (X)

let v: void = undefined; // (O)

let union: string | null | undefined = 'Jinju';

null in JavaScript

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

console.log(n); // null
console.log(typeof n); // object

undefined in JavaScript

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

console.log(u); // undefined
console.log(typeof u); // undefined

Object

// Created by object literal
const person = {name: 'Jinju', age: 26};

// person is not "object" type
// person is "{name: 'Jinju', age: 26}" type

// Created by Object.create(오브젝트 or null)
const dog = Object.create({name: 'ddoa', age: 2});
  • 'Primitive type이 아닌 것'을 나타내고 싶을 때 사용하는 타입

non-primitive type ?

  • not number, string, boolean, bigint, symbol, null or undefined

let obj: object = {};

obj = {name: 'Jinju'};

obj = [{name: 'Jinju'}];

obj = 26; // Error

obj = true; // Error

declare function create(o: object | null): void;

create({ prop: 0 });

create(null);

create(32); // Error

create("string"); // Error

Array

  • 원래 자바스크립트에서 array는 객체이다
  • 사용방법 : 1) Array<타입> 2) 타입[]
let list: number[] = [1, 2, 3];

let list: Array<number> = [1, 2, 3];

let list: (number | string)[] = [1, 2, 3, "4"];

Tuple

let x: [string, number];

x = ["Jinju", 26]; // 순서와 타입이 일치해야 함

x = [32, "someone"]; // Error

const person: [string, number] = ["Jinju", 26];

const [first, second] = person; // destructuring (분해할당)
// person의 요소를 가지고 나와서 [] 안에 넣음

Any

어떤 타입이어도 상관 없는 타입

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

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

any1.toString(); // 타입에러 뜨지 않음 > any이기 때문
  • 타입시스템을 깔끔하게 유지하기 위해 쓰지 않는편이 좋다
  • 컴파일 타임에 타입체크가 정상적으로 이뤄지지 않기 때문이다
  • 그래서 컴파일 옵션중에는 any를 명시해야하는데 쓰지 않으면 오류를 뱉도록 하는 옵션도 존재 > noImpicitAny
let looselyTyped: any = {};

let d = looselyTyped.a.b.c.d;
// ^ = let d: any
  • any는 계속해서 개체를 통해 전파된다
  • 결국 모든 편의는 타입 안전성을 잃는 대가를 치루게 된다
  • 타입 안전성은 TypeScript를 사용하는 주요 이유 중 하나이므로 any를 사용하지 않는 편이 좋다
function leakingAny(obj: any) {
	const a: number = obj.num; // number로 지정해주면 누수를 막을 수 있음
  	const b = a + 1;
  
  	return b;
}

const c = leakingAny({ num : 0 });
c.indexOf('0');

Unknown

  • 응용프로그램 작성 시 모르는 변수의 타입을 묘사해야 할 때 (주로 동적 콘텐츠로 인해)
  • 컴파일러에게 이 변수가 무엇이든 될 수 있음을 알려주는 타입을 제공하기 위해 쓰임
declare const maybe: unknown;

const aNum: number = maybe;

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

if(typeof maybe === 'str') { // typeof typeguard
	const aStr: string = maybe; // (O)
  	const aBoolean: boolean = maybe; // (X)
}
  • TypeScript 3.0 버전부터 지원
  • any와 짝으로 any보다 Type-safe 한 타입
    * any와 같이 아무거나 할당 가능
    • 컴파일러가 타입을 추론할 수 있게끔 타입의 유형을 좁히거나
    • 타입을 확정해주지 않으면 다른 곳에 할당 할 수 없고 사용할수도 없다
  • unknown 타입 사용 시 runtime error를 줄일 수 있을것 같다
    * 사용 전에 데이터의 일부 유형의 검사를 수행해야 함을 알리는 API에 사용할 수 있을 것 같다

Never

보통 return에 사용된다

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

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

function infiniteLoop(): never {
	while(true) {}
}
  • never 타입은 모든 타입의 subtype이며, 모든 타입에 할당 할 수 있다
  • 하지만 never에는 그 어떤 것도 할당할 수 없다 (any조차도)
    * 잘못된 타입을 넣는 실수를 막고자 할 때 사용하기도 한다
let a: string = 'hello';

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

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

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

Void

보통 함수의 반환타입으로 사용됨

function returnVoid(msg: string): void {
	console.log(msg);
  
  	return undefined;
}
  • return 부분에 달아서 아무것도 하지 않겠다 라는 것을 명시적으로 보여주는 행위

0개의 댓글