TIL 22-06-06

thisisyjin·2022년 6월 6일
0

TIL 📝

목록 보기
61/113

TypeScript

🙋‍♂️ Ref Lecture


TypeScript란?

자바스크립트의 단점을 보완하기 위해 'type system'이 추가된 언어.
생산성 높이고, 에러를 줄일 수 있음.
C#이나 Java 처럼 Type을 지정한 언어임.

참고 문서 - TypeScript HandBook
-> JS 개발자를 위한 문서.

MS사에서 제작한 언어임.
(참고로, VS code도 MS사에서 제작하여 둘을 함께 사용했을 때 개발 경험이 좋음)

자바스크립트의 문제점

🙋‍♂️ 타입스크립트가 존재하는 이유는?

  • 자바스크립트의 타입 안정성(Type safety) 문제 때문.
  • 자바스크립트는 매우 유연한 언어임.
[1, 2, 3, 4] + false
// '1,2,3,4false'

-> 배열과 boolean 타입이 모두 string이 되어버림.

위와 같은 말도 안되는 상황도 허용해주기 때문에 타입 안정성이 ❌

  • 그 외에도 함수 실행시 에러를 띄워 실행을 막지는 않는 등의 문제가 있음.
    -> 런타임 에러만 발생함. (런타임 이전에는 에러가 X)


-> TypeScript에서는 런타임 이전에 에러를 발생시켜줌.


TypeScript 문법

📝 타입스크립트 코드 테스트


-> JS와 비교해보면, typescript는 기본적으로 strict 모드가 적용되어 있다.

TypeScript는 런타임 이전에 에러를 감지하고, 만약 에러가 있다면 JavaScript로 컴파일링 하지 않는다.

const yjin  = {
    name: 'thisis',
    age: 24,
}

[1,2,3,4] + true
// js에서는 '1,2,3,4true` 로 정상 실행

const devide = (a, b) => {
  return a / b;
}

devide(3);   // ❗️ error

함수 인자의 타입을 지정해줄 수 있음.

const devide = (a:number, b:number) => {
    return a / b;
}

devide('hello', 'hi'); // ❗️ error - number 형이 아님

타입 변환하려고 할 때, 막아줄 수 있음.

const player = {
  age: 23
}

player.age = true;  // ❗️ error - 


Type System

변수 선언시 어떤 타입인지 명시해줘야 함.

🔻 변수 선언시

  • 데이터와 변수 타입을 명시적으로 정의
  • 자바스크립트처럼 변수만 생성하고 넘어가도 OK -> TS가 알아서 추론해줌. ✅ [권장]


-> 타입 지정을 해주지 않아도 알아서 Type이 지정됨.

타입 지정

❔ 만약 타입을 지정해준다면?

let greeting : number = "hello" 

-> number로 지정했는데 string을 대입해서 에러 발생함.

: number 에 해당하는 부분이 type system 이다.
가독성을 위해 보통 생략하는 것이 좋음. (특정 케이스 제외)

배열 타입 지정

  • 배열의 경우에는 안에 들어있는 요소의 타입을 추론함.
let nums = [1,2,3,4,5]; // number[]
let jobs = ['designer', 'developer', 'engineer']; // string[]

🔻 여러 타입이 섞여있는 배열은 OR|로 모든 타입이 표기된다.

만약 배열의 타입이 아닌 다른 타입을 push 하려고 하면, 에러가 발생한다.

  • 보통 타입을 지정할 때는, 빈 배열일 때 미리 요소의 타입을 지정한 후, push함.
let nums = number[] = [];

nums.push(1);
nums.push("1");  // ❗️ error

객체 타입 지정

  • 각 필드마다 타입을 추론함.
const team = {
    designer: 'injung',
    frontEnd: 'yjin',
    backEnd: 'thisisyjin'
}

  • 직접 지정시 : {}로 적어줘야 한다.
const player : {
name:  string 
age: number
} = {
name: 'yjin',
age: 23
}

Types

기본 type

JS primitive 타입.

  • number
  • string
  • boolean
  • number[]
  • string[]
  • boolean[]

객체 타입 설정

객체의 특정 필드는 필수가 아닌 optional 로 하고 싶다면?

const player : {
name:  string 
age?: number
} = {
name: 'yjin',
// age가 없어도 되고 있으면 number이여야 함.
}

Optional Property

프로퍼티 키 뒤에 ?를 붙여주면 옵셔널한 필드로 설정 가능.

const player : {
name:  string 
age?: number
} = {
name: 'yjin',
age: 9
}

if (player.age < 10) {    // ❗️ error : Object is possibly 'undefined'.
    console.log('you are a child');
} 
  • age 필드가 존재해도, 만약 조건식 등에 값을 사용하려 한다면 에러를 발생시킴.
  • age는 undefined 일수도 있기 때문.

만약 여러개의 객체에 위와 같은 조건을 똑같이 적용해야 할 때,
일일히 코드를 여러번 작성하는 것은 매우 비효율적이다.

-> Type Aliases를 이용하자.

Type Aliases

📌 Alias = 별명.

// 🔻 Type Alias 선언
type Player = {
  name: string,
  age?: number
}

const yjin : Player = { // 그냥 :string 해주듯이 사용하면 됨.
  name: 'Yjin'
}

const injung : Player = {
  name: 'Injung'
}
 		 ...

객체 생성 함수

function playerMaker(name:string) {
  return {
    name
  };
}
  
const yjin = playerMaker('Yjin');
yjin.age = 23;  // ❗️ error - 

-> 리턴하는 객체에 name 프로퍼티만 존재하므로 에러가 발생함.

function playerMaker(name:string, age?:number) {
  return {
    name,
    age
  };
}
  
const yjin = playerMaker('Yjin');

-> 마찬가지로 인수로 받는 age에 ?를 붙여서
optional property를 설정해주면 됨.

다른 방법

함수 인자가 아닌 함수 자체에 type을 지정해줌


type Player = {
  name: string,
  age?: number
}

function playerMaker(name:string) : Player {
  return {
    name
  }
}

함수 실행문 전에 : Player 을 붙여줌. (alias)

다른 방법 - arrow func

const playerMaker  = (name:string) : Player => ({name}) 

const yjin = playerMaker('yjin');
yjin.age = 23;

마찬가지로 함수 블록 전에 : Player 을 붙여준다.


interface vs type

  • interface / type
    객체 타입의 이름을 지정하는 방식.
interface People {
  name: string
  age: number
}

type PeopleInterface {
  name: string
  age: number
}
  • 차이점

확장 방식

  1. interface
interface PeopleInterface {
  name: string
  age: number
}

// 1. 동일 인터페이스 - 선언적 확장 가능 ✅
interface PeopleInterface {
  gender: string
}

// 2. 다른 인터페이스로 - extends로 확장
interface StudentInterface extends PeopleInterface {
  school: string
}
  1. type
type PeopleType = {
  name: string
  age: number
}
// 다른 타입으로 확장만 가능.
type StudentType = PeopleType & {
  school: string
}

❗️ 참고 - [yceffort.kr](https://yceffort.kr/2021/03/typescript-interface-vs-type


interface는 객체만 사용 가능

  • type은 객체가 아닌 일반 string 등도 가능

readonly

type Player = {
  readonly name: string,
  age: number
}

🔻 Example

type Player = {
  readonly name: string,
  age?: number
}
const playerMaker  = (name:string) : Player => ({name}) 
const yjin = playerMaker('yjin');
yjin.name = 'change';

일반 변수(배열)에서도 사용 가능.

const numbers: readonly number[] = [1, 2, 3];

numbers.push(4);  // ❗️ error

❗️ 주의 - readonly는 배열이나 객체의 프로퍼티에만 사용할 수 있음.

Tuple

array 생성 - 최소 길이 / 특정 위치에 특정 타입

const player: [string, number, boolean] = [
    'yjin',
    23,
    true
]
  • type이 달라지면 에러 발생
  • readonly 적용도 가능함. (수정 불가)

undefined, null

const a : undefined = undefined;
const b : null = null;

any

  • 빈 값을 넣어주면 any로 인식함.
const empty = [];   // any
  • typescript 로부터 벗어나고 싶을 때 사용하면 됨.
const a : any[] = [1, 2, 3, 4];
const b : any = true;

console.log(a + b);   // 1,2,3,4true

unknown

let a:unknown;

let b = a + 1;  // ❗️ error - Object is of type 'unknown'

if (typeof a === 'number') {
let b = a + 1;
}
  • unknown은 if 등으로 해당 값의 type을 제한해줘야 값을 사용할 수 있음.
  • 변수의 타입을 미리 알지 못할 때 사용함.

Void

= void = 비어있는 것
= 아무것도 리턴하지 않는 함수.

function hello(): void {
  console.log('hello!')
}

never

자주 사용되지는 않음.

function hello(): never {
  return 'hello';   // ❗️ error - Type 'string' is not assignable to type 'never'
}

function hello(): never {
  throw new Error("hello");
}
  • 타입이 두가지일 수 있는 경우에도 사용됨.
function hello(name: string|number) {
  if (typeof name === 'string') {
    // name은 string
  } else if (typeof name === 'number') {
    // name은 number
  } else {
    // ❗️ name은 never 
  }
}
profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글