관리 메뉴

Jerry

[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part1. 기본 문법편 - (6) : void의 두 가지 사용법 본문

Front/Typescript

[TIL] [타임어택9기][리뉴얼] 타입스크립트 올인원 : Part1. 기본 문법편 - (6) : void의 두 가지 사용법

juicyjerry 2024. 2. 29. 00:24
반응형
void의 두 가지 사용법

 

 

 

 

 

타입스크립트에서 "잉여 속성 검사" 라는 것이 있는데 객체리터럴을 대입할 때 검사를 한다

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

 

 

 

 

 

하지만, 아래 예시처럼 하게 되면 검사를 하지 않는다?

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

 

 

 

 

 

아래 예시에서 함수의 리턴값은 void인데 값이 리턴되는 현상을 볼 수 있다.

function a(): void {
        return '3';
        return undefined;
        return null;
}

const b = a();

interface Human {
    talk: () => void;
}
    
const human: Human = {
    talk() { return; }
    talk() { return undefined; }
    talk() { return 'abc'; } // 이게 된다? void 인데
}

 

 

 

 

 

위에서 리턴값이 void으로 추론되어 보이는데 아닌 경우 같은 헷갈릴 수 있는 케이스들을 살펴보자

 

아래 예시에서 (1)과 (2)에서 에러가 나지는 않는 이유로는,

여기서 이 함수 또는 메서드 void의 의미는 리턴값을 사용하지 않겠다는 의미(3)은 리턴값이 없어야 한다는 의미

// (3) void function
function a(): void {
    return '3';
}

// parameter void
function b(callback: () => void): void {

}
// (1) return 값이 void인 경우도 리턴값이 존재할 수 있다
b(() => {
    return '3';
})

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

const human: Human = {
    //  (2) method void 경우도 리턴값이 존재할 수 있다
    talk() { return 'abc'; }

 

 

 

 

 

함수도 아래와 같이 바디 없이 선언할 수 있다.

다만, 에러가 없으려면 아래에 구현부를 작성해야 한다.

But 구현부를 만들기 싫을 경우, declare 선언(변환 시 사라짐)

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

 

 

 

 

 

 리턴값은 숫자지만 타입은 undefined여서 에러 발생, void는 undefined와 다르다

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

 

 

 

 

 

 

그렇다면 타입이 void일 경우는?

"내가 forEach 를 상위에서 선언했어"라고, 외부에서 선언한 얘들을 타입선언할 때 declare 사용

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



 

 

 

 

매개변수의 void는 리턴값이 무엇이든 상관하지 않겠다 라는 의미
반대로 undefined는 void에 대입 가능! (강의교안 표 참고)

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

 

 

 

 

 

 

이 경우에도 리턴값은 void이다

-> 강제 변환를 해준다

interface D {
    talk: () => void;
}
const d: D = {
    talk() { return 3;}
}

const b = a.talk();

 

 

 

 

 

 

강제 변환은 as를 더 권장 

왜냐하면, 리액트 jsx 작업할 때, 타입스크립트가 태그와 헷갈려해서 잘 이해를 못 하는 경우가 있다

const e = d.talk() as number; // 실수라고 보는데 내가 책임지겠다 하면 as를 사용할 수 있다
const e = d.talk() as unknown as number;
const e = <number><unknown>d.talk();

 

반응형