관리 메뉴

Jerry

[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part1. 기본 문법편 - (7) : unknown과 any(그리고 타입 대입가능표), 타입 좁히기(타입 가드) 본문

Front/Typescript

[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part1. 기본 문법편 - (7) : unknown과 any(그리고 타입 대입가능표), 타입 좁히기(타입 가드)

juicyjerry 2024. 2. 29. 00:37
반응형
unknown과 any(그리고 타입 대입가능표)

 

 

 

 

 

 any를 쓸 바에 unknown을 사용한다
any는 타입핑을 포기(선언), unknown은 정해진 타입만 사용할 수 있게 한다

interface A {
    talk: () => void;
}
const a: A = {
    talk() {
        return 3;
    },
}

const b = a.talk();
const b: any = a.talk();
const b: unknown = a.talk();
(b as A).talk();

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

 

 

 

 

 

 

unknown이 나오는 흔한 경우

에러가 어떤게 나올지 모르기 때문에 에러 타입에 대해 선언해준다 (*에러 사용법은 ts는 건망증이 심하다 편 참고)

try {

} catch (error) {
     error.message
     (error as Error).message // here
     error as AxiosError
}

 

 

 

 

 


 

 

 

 

 

타입 좁히기(타입 가드)

 

 

 

 

 

원시값의 경우

아래 예시는 위험한 코드 why? 문자일수도 있으니깐,

unknown일 경우와 남이 만들어 놓은 코드가 잘못됐을 경우를 제외하고 as 사용을 하지 않는다 

function numOrStr(a: number | string) {
    // Case A
    a.toFixed(1); // error;모든 가능성 고려했을 경우 : string일수도 있어서 경고 띄어줌
    (a as number).toFixed(1); // here

    // Case B (타입가드 기법) : 아래와 같이 타입 추론을 해준다
    if (typeof a === 'number') {
        a.toFixed(1);
    } else {
        a.charAt(3);
    }

    if (typeof a === 'string') {
        a.charAt(3);    
    }   
    if (typeof a === 'boolean') {
        a.toString(); // 절대 실행될 수 없는 코드 ==> never 타입
    }
}

numOrStr('123');
numOrStr(1);

 

 

 

 

 

 

 

array의 경우 

function numOrArray(b: number | number[]) {
    if (Array.isArray(b)) { // number[]
        b.concat(4);
    } else {
        b.toFixed(3);
    }
}

numOrArray(123);
numOrArray([1, 2, 3]);

 

 

 

 

 

 

클래스 : A인지 B인지 구별할 때

여기서 A, B 는 클래스 자체를 의미하는 것이 아니라 인스턴스를 의미한다

 

class A {
    aaa() {}
}

class B {
    bbb() {}
}

function aOrB(param: A | B) { // Here
    if (param instanceof A) {
        param.aaa();
    }
}

aOrB(A()); // 에러
aOrB(new A());
aOrB(new B());
클래스 자체의 타입은 typeof 클래스 (typeof A) 입니다

 

 

 

 

 

 

객체 타입 검사 : 값으로 구별

객체 (구분 방법) : 같은 속성(key)인데 값(value)이 다른 경우(b, c, d)와 아예 속성 이름(key)이 다른 것으로 구별

 

 

case1: 값으로 구분
타입스크립트가 if 구문에 대해 타입 추론을 잘 해준다

// 타입의 값이 b, c, d
type B = { type: 'b', bbb: string };
type C = { type: 'c', ccc: string };
type D = { type: 'd', ddd: string };

function typeCheck(a: B | C | D) {
    if (a.type === 'b') {
        a.bbb;
    } else if (a.type === 'c') {
        a.ccc;
    } else {
        a.ddd;
    }
}

// 타입의 값이 b, c, c
type B = { type: 'b', bbb: string };
type C = { type: 'c', ccc: string };
type D = { type: 'c', ddd: string };

function typeCheck(a: B | C | D) {
    if (a.type === 'b') {
        a.bbb;
    } else if (a.type === 'c') {
        a.ccc;
    } else {
        a.ddd;
    }
}

 

 

 

 

 

 

 

 

case2: 속성으로 구분

 

type B = { type: 'b', bbb: string };
type C = { type: 'c', ccc: string };
type D = { type: 'd', ddd: string };

function typeCheck(a: B | C | D) {
    if ('bbb' in a) {
        a.bbb;
    } else if ('ccc' in a) {
        a.ccc;
    } else {
        a.ddd;
    }
}

 

 

 

 

 

객체 만들 때 좋은 습관 : 객체에 태그 혹은 라벨을 달아놓는다 (type)

const human = { type: 'human' };
const dog = { type: 'dog' };
const cat = { type: 'cat' };

 

 

 

그렇지 않다면(혹은), 차이점을 중점으로 찾아낸다

const human = { talk() };
const dog = { bow(); };
const cat = { meow(); };

if ('talk' in a) {
    a
}

 

 

 

 

반응형