[KDT]FCFE - 5주4일 - TypeScript

Keunyeong Lee·2021년 12월 23일
0
post-thumbnail

TypeScript

  • programming language
  • compiled language ( 전통적은 compiled 는 아니다. )
  • transpile

Compiled / Interpreted

compiled

  • 컴파일이 필요 O
  • 컴파일러가 필요 O
  • 컴파일하는 시점 O => 컴파일 타임
  • 컴파일된 결과물을 실행
  • 컴파일된 결과물을 실행하는 시점

interpreted

  • 컴파일이 필요 X
  • 컴파일러가 팔요 X
  • 컴파일하는 시점 X
  • 코드자체를 실행
  • 코드를 실행하는 시점 O = 런타임

설치

npm i typescript -g

글로벌로 설치.

사용

typescript 로 작성된 파일을 javascript 파일 형식으로 바꿔준다.

tsc 파일명.ts

프로젝트에는 설정 파일을 넣어줘야 한다.

tsc --init

tsconfig.json 이 생성된다.

이 안에 tsc 설정을 넣어줄 수 있다.

tsc 만 실행시키면 프로젝트 안에 ts 파일을 js 파일로 변경해준다.

tsc -w

: watch mode 설정으로 파일이 수정될 때 마다 자동으로 컴파일되도록 한다.

프로젝트에만 ts를 설치하여 사용하기

npm init -y

npm 설정 파일을 만들고

npm i typescript

프로젝트 안에 node_modules 안에 설치한다.

사용할 때는

node_modules/.bin/tsc

node_modules/typescript/.bin/tsc

npx tsc

중 편한것을 사용하면 된다.

프로젝트 전체를 컴파일할 수 있도록

npx tsc --init

First Type Annotation

let a: string; // type annotation 으로 type 설정
a = 'lee';

a = 39; //error

Types

JavaScript : Dynamic Types

TypeScript : Static Types

TypeScript Types

  • Javascript의 ECMAScript 표주에 따른 기본 자료형 + array
    Primitive Type (원시타입)
  • Boolean
  • Number
  • String
  • Null
  • Undefined
  • Symbol
    Object Type (객체타입)
  • Array: object 형
  • 프로그래밍을 도울 몇기지 타입이 더 제공된다.
  • Any, Void, Never, Unknown
  • Enum
  • Tuple: object 형

Boolean

Number

  • 모든 숫자는 부동 소수점 값 이다.
  • 16진수 10진수 2진수 8진수 모두 지원한다.
  • Nan
  • 1_000_000 ( underscoreNum ) 도 지원한다.

String

Template String

  • 행에 걸쳐 있거나, 표현식을 넣을 수 있는 문자열
  • backtick 기호로 사용
  • 포함된 표현식은 &{expr} 과 같이 사용

Symbol

  • ECMAScript2015 의 symbol 이다.

  • new Symbol 로 사용할 수 없다.

  • Symbol 을 함수로 사용해서 symbol 타입을 만들어낼 수 있다.

  • primitive type 의 값을 담아서 사용한다.

  • 고유하고 수정불가능한 값으로 만들어 준다.

  • 주로 접근을 제어하는데 쓰는 경우가 많다.

const sym = Symbol();

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

obj[sym]; // value

함수는 Symbol, 타입은 symbol

null & undefined

  • 소문자만 존재한다.

  • null 은 null 값만 갖고, undefined 는 undefined 만 갖는다.

  • 컴파일 옵션에서 '--strictNullChecks' 를 true 로 하면 null과 undefined는 void나 자기 자신들에게만 할당 할 수 있게 된다.( null과 undefined 를 할당할 수 있게 하려면, union type을 이용해야한다. )

union type

let union : string | null = null;

합집합처럼 사용하면 된다. string 도 되고 null 도 된다는 의미.

null (javascript)

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

undefined (javascript)

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

Object

  • 값을 직접 담지 않고 값을 가르키는 주소를 담고 있다.
// literal 방식으로 만들기
const person1 = {name:'lee', age:20};
// person1 is not "object" type
// person1 is "{name:string, age:number}" type

// 내장 전역객체 Object 를 사용하여 Object 만들기
const person2 = Object.create({name:'lee', age:20});
  • primitive type이 아닌것을 나타내고 싶을 때 사용하는 타입

Array

표현방법

let list : number[] = [1,2,3]; // 더 많이 사용함.

let list : Array<number> = [1,2,3]; //  충돌날 우려가 있음.

let list : number|string[] = [1,2,3,'4']; 
// union 방식으로 사용, 모든 item이 number|string이 된다.

Tuple

표현방법

// 배열 안에 타입 순서와 배열의 길이를 맞춰줘야한다.
// 길이가 맞지 않으면 undefined가 할당되어있다.
let x:[string, number];

x = ["hellw", 20];

//구조분해할당
const [first, second, third] = x;
// first:string, second:number, third:undefined
// 위치에 맞게 타입이 할당된다.

any

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

  • any를 최대한 쓰지 않도록 하는게 좋음

  • 컴파일 타임에 타입 체크가 정상적으로 이뤄지지 않는다.

  • 컴파일 옵션 중에는 any 를 써야하는데 쓰지 않으면 오류를 뱉도록 하는 옵션도 있다.(noImplicitAny)

  • any 는 객체를 통해 전파된다.

  • any 사용으로 인한 편의는 안정성을 잃는 대가로 돌아온다.

  • 타입 안정성은 typeScript 를 사용하는 주요 동기이기 때문에 필요한 경우 외에는 any의 사용을 피해야 한다.

any 전파

  • 객체를 any 로 만들고 객체를 사용하면 any 타입으로 지정된다.
let looselyTyped: any = {};
const d = looselyTyped.a.b.c.d; // any
  • any가 계속 전파되는 것을 막아줘야한다. (leaking)

  • 중간에 number가 들어오면 number type 이 되도록 하는 방식.

unknown

  • typeGuard 를 통해 타입을 지정해서 사용해야 한다.
// 타입만 지정하는 declare 사용
declare const maybe: unknown;

const aNumber: number = maybe;

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


if(typeof maybe === 'string'){
	const aString:string = maybe;
}
  • Typescript 3.0 버전부터 지원
  • any 와 짝으로 any 보다 type-safe 한 타입
    ( any 와 같이 아무거나 할당할 수 있다.)
    ( 컴파일러가 타입을 추록할 수 있게끔 타입의 유형을 좁힌다.)
    ( 타입을 확정해주지 않으면 다른 곳에 할당 할 수없고, 사용할 수 없다.)
  • unknown 타입을 사용하면 runtime error를 줄일 수 있다.
    ( 사용전에 데이터의 일부 유형의 검사를 수행해야 함을 알리는 API에 사용할 수 있다.)

never

  • return 에 사용된다.
function error(message: string): never {
  throw new Error(message);
}

// never type 이 된다.
function fail() {
  return error("failed");
}

function infiniteLoop(): never {
  while(true) {};
}
  • 모든 타입의 subtype 이다. 모든 타입에 할당 할 수 있다.
  • never에는 그 어떤 타입도 할당할 수 없다.
  • 잘못된 타입을 넣는 실수를 막고자 할 때 사용한다.
let a: string = "hello";

if(typeof a !== "string"){
  a; // never type
}

// generic type (type 변수)
type Indexable<T> = T extends string ? T & {[index:string]: any} : never;

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

void

  • 아무것도 반환하지 않는 함수에 사용.
  • 함수의 리턴으로 아무것도 하지 않겠다는 선언.
  • undefined 만 유일하게 할당할 수 있다.

Type System

  • 컴파일러에게 사용하는 타입을 명시적으로 지정하는 시스템
  • 컴파일러가 자동으로 타입을 추론하는 시스템

typescript type system

  • 타입을 명시적으로 지정할 수 있다.
  • 타입을 명시적으로 지정하지 않으면, 타입스크립트 컴파일러가 자동으로 타입을 추론한다.

나만의 타입 만들기

interface PersonInterface {
  name: string;
  age: number;
}

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

function f8(a: PersonInterface): string {
  return `이름은 ${a.name} 이고, 연령대는 ${Math.floor(a.age/10)*10}대 입니다.`;
}

Structural Type System vs Nominal Type System

TypeScript 는 Structural Type 이다.

Structural Type System

  • 구조가 같으면 같은 타입이다.

Nominal Type System

  • 구조가 같아도 이름이 다르면 다른 타입이다.

duck typing

  • 구조가 그렇다면 해당 타입이다. ( ex_ python )

type 호환성

서브타입

  • 포함되는 타입은 subType이 된다.
  • typescript는 함수의 매개변수가 반변, 즉 포함관계에 해당하지 않는 것도 에러가 발생하지 않는다.

같거나 서브 타입인 경우, 할당이 가능하다. => 공변(포함관계 하위로)

함수의 매개변수가 타입만 같거나 슈퍼타입(인 경우, 할당이 가능하다. => 반변(포함관계 상위로)

: strictFunctionTypes 옵션을 켜면 함수의 매개변수가 반변에 해당하지 않을 경우 에러를 통해 경고한다.

Type Alias( 타입 별칭 )

  • 긴 타입명을 별칭을 통해 지정하여 사용한다.
  • 타입을 만드는것은 아니다.
  • interface와 구분하기.

TypeScript Compiler

compile 하기위한 설정 및 옵션은 config에 있다.

config를 잘 알아야 typeScript를 잘 사용할 수 있다.

tsconfig schema

최상위 프로퍼티

compileOnSave
extends
compileOptions ***
files
include
exclude
references
...

compileOnSave

: true 로 설정하면 save 하면 compile 한다.

  • Visual Studio or atom-typescript plugIn 이 해준다.

extends

: tsconfig를 상속하여 사용한다.

github.com/tsconfig/bases

extends 할 설정들이 있다.

files, inclued, exclude

: 셋다 설정이 없으면 전부 컴파일

files

  • 상대 혹은 절대 경로의 리스트 배열
  • exclude보다 강력함

include, exclude

  • glob 패턴 (.gitignore)

  • include ( exclude 보다 약함, * 같은걸 사용하면, .ts/tsx/d.ts 만 include(allowJS)

  • exclude ( 설정안하면- node_modules, bower_components, jspm_packages,outdir 은 default로 제외 ) ( outdir은 항상 제외한다.include에 있어도 제외)

compileOptions

typeRoots, types

  • js의 library 를 사용하기위해 type definition 설정을 한다.

target

  • 빌드의 결과물 버전을 결정한다.
  • 지정하지 않은면 es3이다.

lib

  • 기본 type definition 라이브러리를 어떤 것을 사용하는 결정.
  • lib 지정하지 않으면 (target에 따라 자동으로 사용한다.)
  • lib를 지정하면 lib 배열로만 라이브러리를 사용한다.

outFile

: 내보내는 파일 형태 설정

outDir

: 컴파일된 파일을 저장하는 폴더 생성 설정

outRoot

: 컴파일할 폴더 지정, 지정하지 않으면 컴파일할 파일의 가장 상위가 설정된다.

CompileOptions- strict ***

  • strict type checking options ( 엄격하게 타입을 체크할 옵션들 내장하고 있다.)

  • options

    	--noImplicitAny
    	--noImplicitThis
    	--strictNullChecks
    	--strictFunctionTypes
    	--strictPropertyInitialization
    	--strictBindCallApply
    	--alwaysStrict

--noImplicitAny

  • 명시적이지 않게 any 타입을 사용하여, 표현식과 선언에 사용하면, 에러를 발생
  • 추론을 실패한 경우, any가 맞으면 any라고 지정해야한다.
  • 아무것도 쓰지 않으면 에러 발생
  • 객체에 인덱스 signatur가 없는 경우 발생하는 오류를 예외 처리함(ex. { bar:10 } => { 'bar':10 })

--noImplicitThis

  • 명시적이지 않게 any 타입을 사용하여, this 표현식에 사용하면, 에러를 발생한다.
  • 첫번째 매개변수 자리에 this를 놓고, this에 대한 타입을 표현하지 않으면 오류 발생
  • javascript 에서는 매개변수에 this 를 넣으면 SyntaxError 발생
  • call/apply/bind 와 같이 this 를 대체하여 함수 콜 하는 용도로도 쓰인다.
  • this를 any 로 명시적으로 지정하는 것이 합리적이다.( 구체적인 사용 타입이 있는 경우 제외 )
  • class 에서는 this를 사용하면서, noImplicitThis와 관련한 에러가 나지 않는다. (당연하게도)
  • class 에서 construcktor 를 제외한 멤버 함수의 첫번째 매개변수도 일반 함수와 마찬가지로 this 를 사용 할 수 있다.

--strictNullChecks

  • 설정해놓지 않으면 모든 타입은 null, undefined 값을 가질 수 있다.
  • string 으로 타입을 지정해도 null 혹은 undefined 값을 할당할 수 있다는 것이다.
  • 설정을 적용하면 모든 타입은 null, undefined 값을 가질 수 없고 가지려면 union type을 이용해서 직접 명시해야 한다.
  • any 타입은 null 과 undefined 를 갖는다. 예외적으로 void 타입의 경우 undefined 를 갖는다.

--strictFunctionTypes

  • 반환 타입은 공변적, 인자 타입은 반공변적 이어야함
  • TS 에서는 인자 타입이 공변적이면서, 반공변적이다.
  • 옵션을 켜면 인자타입이 공변적이면 에러를 발생 시킨다.

--strictPropertyInitialization

  • 정의되지 않은 클래스의 속성이 생성자에서 초기화되었는지 확인한다.
  • 할당되지 않으면 에러 표시를 해준다.
  • 이 옵션은 -- strictNullChecks를 사용하도록 설정해야 한다.

--strictBindCallApply

  • bind, call, apply 에 대해 더 엄격한 검사 수행
  • function 의 내장 함수인 bind / call / apply 를 사용할 때, 엄격하게 체크하도록 하는 옵션이다.
  • bind 는 해당 함수안에서 사용할 this와 인자를 설정해주는 역할을 하고, call과 apply는 this와 인자를 설정한 후, 실행까지 합니다.
  • call과 apply는 인자를 설정하는 방식에서 차이점이 있다. call은 함수의 인자를 여러 인자의 나열로 넣어서 사용하고, apply는 모든 인자를 배열 하나로 넣어서 사용한다.

--alwaysStrict

  • 각 소스 파일에 대해 javascript의 strict mode로 코드를 분석하고, 엄격하게 사용을 해제한다.
  • syntex 에러가 ts error 로 나온다.
  • 컴파일된 JavaScript파일에 "use strict" 추가됨

strict 를 true로 하고 사용해야한다. 필수 옵션!

profile
🏃🏽 동적인 개발자

0개의 댓글