"Boldness has genius, power, and magic in it." - Johann Wolfgang von Goethe

TypeScript

[TS] TypeScript Basic Types 정리

Toproot 2021. 8. 31. 09:38
728x90
728x90

 

  • 기본 프로젝트 생성 후 아래 타입 실습!
// package.json 생성
npm init -y

// 개발용으로 TS 설치
npm i typescript -D

// 프로젝트 루트경로에 tsconfig.json 파일이 생긴 것.
npx tsc --init

// tsconfig.json에서 이부분 확인하기.
"strict": true,

// JS로 컴파일
npx tsc

// 파일 실행
noe [파일명]

 

Boolean

let isDone: boolean = false;

isDone = true;

console.log(typeof isDone) // boolean

// 아래와 같이 리터럴로 직접 primitive타입을 사용하는 것이 일반적..
let isOk: Boolean = true;

// 잘못된 사례
let isNotOk: boolean = new Boolean(true);

 

Number

  • JS와 같이, TS의 모든 숫자는 부동 소수점 값 입니다.
  • TS는 16진수 및 10진수 리터럴 외에도, ECMAScript 2015에 도입된 2진수 및 8진수를 지원합니다.
  • NaN
  • 1_000_000 (백만) 과 같은 표기 가능
// 10진수
let decimal: number = 6;

// 16진수
let hex: number = 0xf00d;

// 2진수
let binary: number = 0b1010;

// 8진수
let octal: number = 0o744;

// NaN
let notANumber: number = NaN;

// underscore를 활용해서 백만 표기 가능.
let underscoreNum: number = 1_000_000;

 

 

String

  • 다른 언어에서와 마찬가지로 텍스트 형식을 참조하기 위해 'String'형식을 사용합니다.
  • JS와 마찬가지로 TS는 문자열 데이터를 둘러싸기 위해 큰따옴표나 작은따옴표를 사용합니다.
let name: string = "mark";
name = 'anna';

Tempalte String

  • 행에 걸쳐 있거나, 표현식을 넣을 수 있는 문자열
  • 이 문자열은 backtic(=backquote) 기호에 둘러쌓여 있습니다.
  • 포함된 표현식은 '${expr}' 와 같은 형태로 사용합니다.
let fullName: string = `Bob Bobbington`;
let age: number = 38;

let sentence: string = `Hello, my name is ${ fullName }.

I'll be ${ age + 1 } 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.";

 

 

Symbol

  • ECMAScript 2015의 Symbol 입니다.
  • new Symbol로 사용할 수 없습니다.
  • Symbol 을 함수로 사용해서 symbol 타입을 만들어낼 수 있습니다.
console.log(Symbol('foo') === Symbol('foo'));

// Symbol을 사용하려면 tsconfig.json에서 lib 설정.
"lib": ["ES2015", "DOM"],

 

  • 프리미티브 타입의 값을 담아서 사용합니다.
  • 고유하고 수정불가능한 값으로 만들어줍니다.
  • 그래서 주로 접근을 제어하는데 쓰는 경우가 많았습니다.
// 고유한 값.
const sym = Symbol();

const obj = {
  // Symbol로 만든 변수를 가져다가 사용함.
  // 함수로 사용할 때는 대문자 Symbol
  // 타입으로 사용할 때는 소문자 symbol
  [sym]: "value",
};

// obj["sym"]
obj[sym]

 

 

Null & Undefined

  • TS에서, undefined와 null은 실제로 각각 undefined 및 null 이라는 타입을 가집니다.
  • void와 마찬가지로, 그 자체로는 그다지 유용하지 않습니다.
  • 둘다 소문자만 존재합니다.
// 이 변수들에 해당할 수 있는 것들은 거의 없다.

let u: undefined = undefined;
let n: null = null;

 

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

  • primitive type이 아닌것을 나타내고 싶을 때 사용하는 타입

non-primitive type

  • not number, string, boolean, bigint, symbol, null, or undefined.
// create by object literal
const person1 = {name: 'Mark', age: 39};

// person1 is not "object" type.
// person1 is "{name: string, age: number}" type.

// create by Object.create
const person2 = Object.create({name: 'Mark', age: 39});
let obj: object = {};

obj = {name: 'Mark'};

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

obj = 39; // Error

obj = true; // Error

obj = 100n; // Error

obj = Symbol(); // Error

obj = null; // Error

obj = undefined;  // Error
  • primitive 타입을 사용하지 못하도록 하는 제약조건.
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
Object.create(0); // Error

 

 

Array

  • 원래 JS에서 array는 객체입니다.
  • 사용방법
    • Array<타입>
    • 타입[]
// type annotation
// 배열 표현방법에 집중
// 1. 권장
let list: number[] = [1, 2, 3];

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

// 요소들을 공통의 타입으로 묶을 수 있어야 array라 표현하는 것이 좋다.

// 배열의 타입이 다를 경우 union 사용
let list3: (number | string)[] = [ 1, 2, 3, "4"];

 

 

Tuple

// 튜플
// 앞 뒤로 다른 타입을 대괄호에 넣어줌.
let x: [string, number];

// 순서, 타입, 길이가 처음 설정한 대로 작성해야함.
x = ["hello", 39];

// 길이 : 2(length) 이상은 값이 들어갈 수 없도록 undefined로 지정됨.
// x[3] = "world";

const person: [string, number] = ["Mark", 39]

// destructuring 분해할당
// const [first, second] = person; // first = string, second = number

// const [first, second, third] = person; // 길이 오류

 

 

Any

  • 어떤 것이나 된다. = 정확하게 알고 사용하기!
  • 어떤 타입이어도 상관없는 타입입니다.
  • 이걸 최대한 쓰지 않는게 핵심입니다.
  • 왜냐면 컴파일 타임에 타입 체크가 정상적으로 이뤄지지 않기 때문입니다.
  • 그래서 컴파일 옵션 중에는 any를 써야하는데 쓰지 않으면 오류를 뱉도록 하는 옵션도 있습니다.
    • nolmplicitAny
// any
// any 함수
function returnAny(message: any): any{ // no implished any 옵션
  console.log(message)
}

const any1 = returnAny('리턴은 아무거나') // any 타입

any1.toString();

// any를 쓸 수 밖에 없는 상황이 있음.

 

  • any는 계속해서 개체를 통해 전파됩니다.
  • 결국, 모든 편의는 타입 안정성을 잃는 대가로 온다는 것을 기억하십시오.
  • 타입 안정성은 TypeScript를 사용하는 주요 동기 중 하나이며 필요하지 않는 경우에는 any를 사용하지 않도록 해야합니다.
let looselyTyped: any = {};

// any가 개체를 통해서 계속 전파되는 예시
// 타입안정성을 잃는 결과를 가져온다.
let d = looselyTyped.a.b.c.d;
// ^ = let d: any

function leakingAny(obj: any) {
  const a: number = obj.num; // num이 들어올 경우 : number라고 타입지정을 해줌으로써 누수를 막음.
  const b = a + 1;
  return b;
}

const c = leakingAny({ num: 0 }); // c도 any가 됨.
// c.indexOf(0);

 

 

Unknown

  • any가 가지고 있는 타입불안전성을 조금이나마 해소하기 위해 나온 대체자
  • 응용 프로그램을 작성할 때는 모르는 변수의 타입을 묘사해야 할 수 도 있습니다.
  • 이러한 값은 동적 콘텐츠 (예: 사용자로부터, 또는 우리 API의 모든 값을 의도적으로 수락하기를 원할 수 있습니다.
  • 이 경우, 컴파일러와 미래의 코드를 읽는 사람에게 이 변수가 무엇이든 될 수 있음을 알려주는 타입을 제공하기를 원하므로 unknown 타입을 제공합니다.

  • TS 3.0 버전부터 지원
  • any와 짝으로 any보다 Type-safe한 타입
    • any와 같이 아무거나 할당할 수 있다.
    • 컴파일러가 타입을 추론할 수 있게끔 타입의 유형을 좁히거나
    • 타입을 확정해주지 않으면 다른 곳에 할당 할 수 없고, 사용할 수 없다.
  • unknown 타입을 사용하면 runtime error 를 줄일 수 있을 것 같다.
    • 사용 전에 데이터의 일부 유형의 검사를 수행해야 함을 알리는 API에 사용할 수 있을 것 같다.
// unknown
declare const maybe: unknown;

  const aNumber: number = maybe; //Type 'unknown' is not assignable to type 'number'.

// 타입가드
if (maybe === true) {
  const aBoolean: boolean = maybe; // boolean(true) 타입

  // const aString: string = maybe; // maybe가 true 이므로 오류
}

// typeof 타입가드
if (typeof maybe === 'string' ) {
  const aString: string = maybe;

  // const aBoolean: boolean = maybe;
}

 

 

Never

  • never 타입은 모든 타입의 subtype이며, 모든 타입에 할당 할 수 있습니다.
  • 하지만, never 에는 그 어떤 것도 할당할 수 없습니다.
  • any 조차도 never 에게 할당 할 수 없습니다.
  • 잘못된 타입을 넣는 실수를 막고자 할 때 사용하기도 합니다.
// never

function error(message: string): never { // never를 리턴한다는것은 아무것도 리턴하지 않는다는 것.
    throw new Error(message);
}

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

function infiniteLoop(): never {
    // 무한루프이면 넘어가지 않기 때문에 never 사용
    while(true) {}
}

declare const a: string | number;

if (typeof a !== 'string') {
    // a가 string이 아닌경우에는 아무것도 할당하지 못한상태 => never
    // string | number일 때는 string이 아니라 number만 남게되어 number로 할당.
    a;
}

// +
// 조건부 타입 generic
// string 이면 T, 아니면 never
type Indexable<T> = T extends string ? T & {[index: string]: any} : never;

type ObjectIndexable = Indexable<{}>; // type = never

// const b: Indexable<{}> = ''; // 타입 오류..

 

Void

  • 어떤 타입도 가지지 않는 빈 상태.
  • 값은 없고 타입만 존재. 소문자로 사용.
  • 일반적으로 변수에 어노테이션하는 것이 아니라 값을 가지지 않는 undefined를 반환할때 return 타입으로 사용.
  • undefined가 있기 때문에 TS에서는 많이 사용되지는 않음.
// void
// void라는 타입으로 추론이 됨.
function returnVoid(message: string) {
  console.log(message);

  return ; // 또는 return undefined;
}

const r = returnVoid('리턴이 없다.'); // r의 타입은 void

// 정상적인 사용방법, 아무것도 타입을 할당하지 않겠다는 의미.
returnVoid('리턴이 없다.');

// 리턴부분에 달아서 아무것도 하지 않겠다고 명시적으로 표현할 때 사용

 

 

 

728x90
728x90