본문 바로가기

TYPESCRIPT

타입스크립트 학습내용 정리

 

배열선언, 튜플선언

let fruits: string[] = ['Apple', 'Banana', 'Mango'];
let fruits: Array<string> = ['Apple', 'Banana', 'Mango'];
let tuple: [string, number];
tuple = ['a', 1];
tuple = ['a', 1, 2]; // Error - TS2322
tuple = [1, 'a']; // Error - TS2322

타입선언

불리언 

let isBoolean: boolean;
let isDone: boolean = false;

 

배열(두가지 방법)

let fruits: string[] = ['Apple', 'Banana', 'Mango'];
let fruits: Array<string> = ['Apple', 'Banana', 'Mango'];

 

배열의 타입 동시 선언(A_type | B_type)

let array: (string | number)[] = ['Apple', 1, 2, 'Banana'];
let array: Array<string|number> = ['Apple', 1, 2, 'Banana'];

 

배열의 any타입 선언(넣을 값을 모르겠는 경우)

let someArr: any[] = [0, 1, {}, [], false];

 

배열 커스텀 타입 (IUser라는 타입을 만들게 됨)

interface IUser {
    name: string,
    age: number,
    inVaild: boolean,
}

 사용방법(일반 타입처럼 사용)

let userArr: IUser[] = [
    {
        name: 'Neo',
        age: 85,
        inVaild: true,
    },

]

 

 

특이한 배열선언

let array = 10[];
array = [10];
array.push(10);
array.push(11); // 에러 발생 TS2345

 

읽기 전용 배열(redonly, ReadonlyArray)

let arrA: readonly number[] = [1,2,3,4];
let arrB: ReadonlyArray<number> = [0, 9, 8, 7];

값을 바꾸거나 push하는 경우, read only라서 에러발생

arrA[0] = 123;// TS2542
arrA.push(123);// TS2339

 

 

타입선언 2

튜플 일반 배열과 다른점 배열의 길이 정함

let tuple: [string, number];
tuple = ['a', 1];
tuple = ['a', 1, 2]; // TS2322
tuple = [1, 'a']; // TS2322

 

여러 배열 선언 가능

let user: [number, string, boolean] = [1234, 'HEROPY', true];
console.log(user[0]); //1234
console.log(user[1]); //'HEROPY'
console.log(user[2]); // true

 

 

tuple을 이용한 2차원 배열

let users: [number, string, boolean] []
let users: Array<[number, string, boolean]>;
users = [[1, 'Neo', true], [2, 'Evan' ,false], [2, 'Lewis', true]]

 

값으로 타입 대신 가능

// 값으로 타입 대신 가능
let tuple: [1, number];
tuple =[1, 2];
tuple =[1, 3];
tuple =[2, 3]; //error T2322

 

tuple은 길이를 제한하는 것 할당은 안되지만 push는 가능하다.

let tuple: [string, number];
tuple = ['a', 1];
tuple = ['b', 2];
tuple.push(3);
console.log(tuple); //['b',2, 3]
tuple.push(true); //TS2345

 

튜플에 readonly 사용가능

let a: readonly [string, number] = ['Hello', 123];
a[0] ='World'; //TS2540

 

 

enum 숫자형, 문자형

초기값 설정이 없다면 0부터 1씩 증가

enum Week {
    Sun, //0
    Mon, //1
    Tue, //2
    Wed, //3
    Thu, //4
    Fri, //5
    Sat //6
}

 

초기값 설정시

enum Week {
    Sun, //0
    Mon=22,
    Tue, //23
    Wed, //24
    Thu, //25
    Fri, //26
    Sat //27
}
 
 
console.log(Week); 결과

 

key:Sun value: 0

console.log(Week);
console.log(Week.Sun); // 0 키로값획득하기
console.log(Week[0]); //'Sun' 
// 역 매핑 가능(역추적가능)숫자형에만 존재
console.log(Week['Sun']); // '.'이 없음 유의해야함, 0 값으로 키 획득하기
console.log(Week.Mon); //22
console.log(Week.Tue) //23

 

 

문자형 (역추적 불가)

enum Color {
    Red = 'red',
    Green ='green',
    Blue = 'blue'
}
console.log(Color.Red); //red
console.log(Color['Green']); //green

 

 

Any :어떤 값도 할당할 수 있음
강한 시스템 장점을 위해 컴파일 "noTmplicitAny": true 를 통해 Any 사용 시 에러를 발생시킬 수 있음
let any:any = 123;
any ='Hello world';
any={}; // 빈오브젝트
any=null;
console.log(any);

 

Unknown: 어떤 값도 할당 불가능

let a: any = 123;
let u: unknown = 123;

let v1: boolean = a; //모든 타입(any)은 어디든 할당 가능
let v2: number = u; //에러

let v3: any = u; //OK any에는 할당이 가능하다
let v4: number = u as number; //타입을 단언하면 할당 가능

 

 

객체: object

그다지 유용하진 않음(여러 타입의 상위 타입이라서)

let obj: object = {};
let arr: object = [];
let func: object = function () {};
let nullValue: object = null;
let date: object = new Date();

 

let userA: { name: string, age: number } = {
  name: 'HEROPY',
  age: 123
};

let userB: { name: string, age: number } = {
  name: 'HEROPY',
  age: false, // Error
  email: 'thesecon@gmail.com' // Error
};

 

반복적으로 사용하는 경우 Interface를 이용하는게 나을 수 있음

 

 

Null undifined(타입들 중 가장 하위속성) 서로의 타입에 할당 가능

let num: number = undefined;
let str: string = null;
let obj: { a: 1, b: false } = undefined;
let arr: any[] = null;
let und: undefined = null;
let nul: null = undefined;
let voi: void = null;
// ...

 

컴파일 옵션 "strictNullChecks": true를 통해 서로의 타입에 더이상 할당 불가능
 +
let voi: void = undefined; // ok void에는 undifined할당 가능

 

void

일반적으로 값을 반환하지 않는 함수 ->undifined 반환

 function hello(msg: string): undefined {
     console.log(`Hello ${msg}`);
 }

 

 

그렇다고 해서 함수에 undifined를 할당할 수는 없다

function hello(msg: string): undefined {
   console.log(`Hello ${msg}`);
}

// Error - TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

 

Never 절대 발생하지 않을 값, 어떤 타입도 적용 불가

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

 

 

빈배열을 타입으로 잘못설정한 경우 볼 수 있음

const never: [] = [];
never.push(3); // Error - TS2345: Argument of type '3' is not assignable to parameter of type 'never'.

 

Union 두 개 이상의 타입 허용

- ()괄호 선택사항

-|

let union: (string | number);
union = 'Hello type!';
union = 123;
union = false; // Error - TS2322: Type 'false' is not assignable to type 'string | number'.

 

intersection &를 이용해 두개의 타입 조합

interface IUser {
    name: string,
    age: number
  }
  interface IValidation {
    isValid: boolean
  }

위와같이 인터페이스가 두개일때 

  const heropy: IUser = {
    name: 'Heropy',
    age: 36,
    isValid: true // Error -  TS2322: Type '{ name: string; age: number; isValid: boolean; }' is not assignable to type 'IUser'.
  };

이와같이 실행 시 에러

 

하지만 &를 사용시

  const neo: IUser & IValidation = {
    name: 'Neo',
    age: 85,
    isValid: true
  };
  // 혹은 기존 타입(IUser, IValidation)과 비슷하지만, 정확히 일치하는 타입이 없다면 새로운 타입을 생성해야 합니다.
  interface IUserNew {
    name: string,
    age: number,
    isValid: boolean
  }
  const evan: IUserNew = {
    name: 'Evan',
    age: 36,
    isValid: false
  };

 

 

함수 

화살표 함수 가능

// myFunc는 2개의 숫자 타입 인수를 가지고, 숫자 타입을 반환하는 함수.
let myFunc: (arg1: number, arg2: number) => number;
myFunc = function (x, y) {
  return x + y;
};

// 인수가 없고, 반환도 없는 경우.
let yourFunc: () => void;
yourFunc = function () {
  console.log('Hello world~');
};

 

 

타입추론

타입이 선언 되지않은 경우 타입추론함

let num = 12;
num = 'Hello type!'; // TS2322: Type '"Hello type!"' is not assignable to type 'number'.

number선언을 하지 않았지만 추론하였음

 

추론하는 경우

1. 초기화된 변수

2. 기본값이 설정된 매개 변수

3. 반환 값이 있는 함수

 

// 초기화된 변수 `num`
let num = 12;

// 기본값이 설정된 매개 변수 `b`
function add(a: number, b: number = 2): number {
  // 반환 값(`a + b`)이 있는 함수
  return a + b;
}

 

 

 

타입단언(assertions)

타입스크립트보다 내가 더 타입을 잘 아는 경우 힌트를 주기

function someFunc(val: string | number, isNumber: boolean) {
  // some logics
  if (isNumber) {
    val.toFixed(2); // Error - TS2339: ... Property 'toFixed' does not exist on type 'string'.
  }
}

val은 유니온타입

 isNumber이라는 변수명을 보고 

우리는 val이 숫자임을 알 수 있으나  컴퓨터는 모름

 

단언하는 방법

function someFunc(val: string | number, isNumber: boolean) {
  // some logics
  if (isNumber) {
    // 1. 변수 as 타입
    (val as number).toFixed(2);
    // Or
    // 2. <타입>변수
    // (<number>val).toFixed(2);
  }
}

 

2번은 jsx파싱문제때문에 .tsx파일에서 사용 불가

 

 

Non-null단언 연산자

!를 사용

피연산자가 nullish(null이나 undifined)가 아님을 단언

// Error - TS2533: Object is possibly 'null' or 'undefined'.
function fnA(x: number | null | undefined) {
  return x.toFixed(2);
}

// if statement
function fnD(x: number | null | undefined) {
  if (x) {
    return x.toFixed(2);
  }
}

// Type assertion
function fnB(x: number | null | undefined) {
  return (x as number).toFixed(2);
}
function fnC(x: number | null | undefined) {
  return (<number>x).toFixed(2);
}

// Non-null assertion operator
function fnE(x: number | null | undefined) {
  return x!.toFixed(2);
}

 

// Error - TS2531: Object is possibly 'null'.
document.querySelector('.menu-item').innerHTML;

// Type assertion
(document.querySelector('.menu-item') as HTMLDivElement).innerHTML;
(<HTMLDivElement>document.querySelector('.menu-item')).innerHTML;

// Non-null assertion operator
document.querySelector('.menu-item')!.innerHTML;

컴파일 환경에서 체크하기 어려운 DOM사용에서 유용

 

 

타입 가드

function someFunc(val: string | number, isNumber: boolean) {
  if (isNumber) {
    (val as number).toFixed(2);
    isNaN(val as number);
  } else {
    (val as string).split('');
    (val as string).toUpperCase();
    (val as string).length;
  }
}

val를 반복적 선언

보기 좋지 않음

 

그래서 타입가드 사용

 

함수에 출력 타입을 is number로 지정

// 타입 가드
function isNumber(val: string | number): val is number {
  return typeof val === 'number';
}
function someFunc(val: string | number) {
  if (isNumber(val)) {
    val.toFixed(2); //toFixed얘는 뭐지?
    isNaN(val);
  } else {
    val.split('');
    val.toUpperCase();
    val.length;
  }
}

 

 

'TYPESCRIPT' 카테고리의 다른 글

타입스크립트: 유틸리티 타입  (0) 2022.04.11
타입스크립트: 모듈  (0) 2022.04.11
타입스크립트: 함수, 클래스  (0) 2022.04.10
타입스크립트: 제네릭  (0) 2022.04.10
타입스크립트: 인터페이스  (0) 2022.04.08