반응형
250x250
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

TS 기본 지식 본문

TS/TS(with ZeroCho)

TS 기본 지식

5_hyun 2022. 8. 11. 00:18

함수 리턴값 타입 위치

function add(x: number, y: number): number {
  return x + y;
}

리턴값 타입 위치는 이렇게 매개변수 뒤쪽에 붙여야한다.

function add(x: number, y: number): number;

function add(x, y) {
  return x + y;
}

혹은 이렇게 타입만 선언하고 다음에 내용을 선언하는 경우도 있다.

화살표 함수

const add: (x: number, y: number) => number = (x, y) => x + y;

이렇게 매개변수의 타입 위치가 찾기 어렵게 있다. 이런 경우 타입을 다 지웠을 때 js 문법에 맞게 되도록 코딩을 하면 어느정도 맞다.

type Add = (x: number, y: number) => number;
const add: Add = (x, y) => x + y;

혹은 이렇게 type을 빼줄 수 있다.

interface Add {
  (x: number, y: number): number;
}

const add: Add = (x, y) => x + y;

interface를 통해서도 타입을 선언할 수 있고 많이 사용하는 방식이다.

객체

const obj: {lat:number, lon:number} = {lat:37.5, lon:127.5}

이렇게 두면된다. 마찬가지로 타입 부분을 지웠을 때 js 문법에 맞아야한다.

배열

const arr: string[] = ["123", "456"];

[]를 붙여주면 된다.

const arr2: Array<number> = [123, 456];

이렇게 Array 제네릭을 사용할 수 있다.

튜플

튜플은 개수가 고정된 배열이다.

const arr: [number, number, string] = [123, 456, "hello"];

이렇게 각각 타입을 만들면된다.

원시값

const f: true = true;
const g: 5 = 5;

이렇게 값 자체를 고정할 수 있다. 왜냐하면 const는 항상 고정된 값이기 때문이다.

타입 추론

-const

ts에서 const를 하면 스스로 타입을 알아챈다.

const a: string = '5';

근데 여기서 string이나 number 타입을 주게되면 범위가 넓어져서 더 안좋아진다.

const a = '5';

따라서 const의 경우에는 그냥 써주는 것이 좋다.

 

-ts 타입 추론

ts는 타입을 거의 예측한다. 따라서 ts가 제대로 예측을 하면 굳이 타입 선언을 할 필요는 없다. 만약 예측하지 못하거나 any로 예측하면 그 때 타입을 선언해줘도 된다.

as

let a = 123;
a = 'hello' as unknown as number;

as는 강제로 타입을 바꾸고 에러가 사라진다.

never 타입

빈 배열은 never 타입이라 반드시 타입을 지정해야한다.

 

-never에 대한 더 자세한 글

https://ui.toast.com/weekly-pick/ko_20220323

 

타입스크립트의 Never 타입 완벽 가이드

타입스크립트의 never 타입은 다른 타입만큼 흔하게 사용되거나 피할 수 없는 것이 아니기 때문에 충분히 논의되고 있지 않다. 타입스크립트 초보자는 조건부 타입 같은 고급 타입을 처리하거나

ui.toast.com

type 지정하고 사용하기

사진처럼 타입을 지정해두면 이 타입을 선언하는 변수에서 자동적으로 값을 추천해준다.

 

혹은 이렇게 2가지 중 하나를 추천받을 수도 있다.

enum

const enum EDirection {
    Up,
    Down, 
    Left,
    Right
}

const a = EDirection.Up;

UP은 0, Down은 1, Left은 2, Rigjt은 3이라서 이렇게 하면 a = 0이다. 

const enum EDirection {
    Up = 3,
    Down,
    Left,
    Right
}

const a = EDirection.Up;

이렇게 초기 값을 지정해주면 순서대로 3, 4, 5 ,6이 되고 a는 3이다.

 

-객체로 표현한 방법

const ODirection = {
  Up: 0,
  Down: 1,
  Left: 2,
  Right: 3,
} as const;

객체로 표현하는 것이 좀 더 좋다. as const를 쓰면 타입이 더 명확해진다. 안 사용하면 타입이 number가 된다.

readonly는 읽기 전용이라 수정을 못한다. 실제 코딩할 때 앞에 붙여서 사용해도 된다.

typeof

obj는 값이다. 근데 타입으로 사용하고 싶으면 typeof를 붙이면 된다.

keyof를 붙이면 키들 뽑아내고 싶을 때 사용하면 된다. 즉 a, b, c를 타입으로 사용할 수 있다.

 

이렇게 하면 value들의 타입값만 가져온다.

type와 interface

type A = { a: string };
const a: A = { a: "hello" };

interface B {
  a: string;
}
const b: B = { a: "hello" };

이렇게 type와 interface로 사용할 수 있다. 둘의 차이점은 type은 간단한거에 사용하고 interface는 좀 더 객체 지향적인 것을 할 때 사용하면 좋다.

interface A {
  a: string;
}
interface A {
  b: string;
}
const obj1: A = { a: "hello", b: "world" };

type B = { a: string };
type B = { b: string };

interface는 이름을 중복으로 지어도 되지만 type는 중복으로 지으면 안된다.

&

type A = { hello: "world" } & { zero: "cho" };
const a: A = { hello: "world", zero: "cho" };

& 연산자는 객체에서 사용할 수 있다. 모든 속성이 다 있어야 한다.

 

type Animal = { breath: true };
type Poyouryu = Animal & { breed: true };
type Human = Poyouryu & { think: true };

const z: Human = { breath: true, breed: true, think: true };

이렇게 상속의 개념을 사용할 수 있다.

interface

interface A {
  breath: true;
}

interface B extends A {
  bread: true;
}

const b: B = { breath: true, bread: true };

JAVA에서 처럼 이렇게 확장해서 사용이 가능하다.

 

type Animal = { breath: true };
type Poyouryu = Animal & { breed: true };
type Human = Poyouryu & { think: true };

const z: Human = { breath: true, breed: true, think: true };

interface A {
  breath: true;
}

interface B extends Human {
  bread: true;
}

const b: B = { breath: true, bread: true, think: true };

type과도 같이 사용이 가능하다.

잉여 속성 검사

interface A {
  a: string;
}
const obj = { a: "hello", b: "world" };
const obj1: A = obj;

interface 안에 b가 없는데

const obj1: A = { a: "hello", b: "world" };

이렇게 하면 에러가 난다. 하지만 맨 위 코드처럼 한게를 거치면 에러가 나지 않는다.

void 타입

만약 함수에 리턴 값이 있으면 void 타입을 넣으면 안된다. 대신에 undefined를 return 하는 것은 된다. 하지만 null을 리턴하는 것은 안된다.

=> 따라서 return; 이렇게만 있거나 리턴 값이 없는 함수가 void 타입이 된다.

 

function a(callback: () => void): void {}

interface Human {
  talk: () => void;
}

void는 3가지 종류가 있다.

1. return 값이 void

2. 매개 변수가 void

3. 메서드가 void

 

이 중에서 매개 변수가 void, 메서드가 void 이 2가지는 리턴 값이 존재할 수 있다. 즉, 직접적인 return 값이 void인 경우 제외하고 리턴 값이 있을 수 있다.

 

-예시1

declare function forEach(arr: number[], callback: (el: number) => void): void;

let target: number[] = [];
forEach([1, 2, 3], (el) => target.push(el));

이런 경우에는 callback에서 매개변수 값이 number이다. 하지만 void로 해도 에러가 발생하지 않는다. 왜냐하면 void는 어떤 값으로 해도 상관 없다는 의미이기 때문이다.

여기서 declare는 외부에서 만들어져 있는 함수나 변수를 가져와서 쓰겠다는 의미이다.

 

-예시2

interface A {
  talk: () => void;
}

const a: A = {
  talk() {
    return 3;
  },
};
const b = a.talk();

이렇게 하면 원래 b에는 3이 들어있어야 한다. 하지만 void는 이를 무시하고 b는 void가 된다.

이렇게 나온다. 따라서 return 값의 타입이 void이면 return 값을 안 넣는 것이 맞다.

 

-강제 타입 변환

const b = a.talk() as unknown as number;

만약 자신이 책임질 수 있으면 이렇게 타입을 변경할 수 있다. 하지만 이 방식은 웬만하면 안하는 것이 좋다.

any와 unknown

결론부터 말하면 any 쓸 바엔 unknown을 쓰는 것이 낫다.

왜냐하면 any를 사용하면 ts가 타입 검사를 아예 하지 않는다. 따라서 ts를 쓰는 의미가 없어진다.

unknown 개발자가 직접 타입을 정해줄 수 있다. Error의 타입은 unknown이다.

728x90
반응형

'TS > TS(with ZeroCho)' 카테고리의 다른 글

TS와 건망증  (0) 2022.08.20
리턴값, 매개변수의 대입 범위  (0) 2022.08.20
타입을 만드는 법  (0) 2022.08.20
제네릭  (0) 2022.08.18
TS 기본 기식(2)  (0) 2022.08.17
Comments