[우아한타입리액트] 2장. 타입(2)

Lina Hongbi Ko·2024년 11월 27일
0
post-thumbnail

2. 타입 (2)


*트리쉐이킹(tree-shaking): 자바스크립트, 타입스크립트에서 사용하지 않는 코드를 삭제하는 방식. 나무를 흔들면 죽은 나뭇잎이 떨어지는 모습을 보고 이름을 따왔다고 한다. ES6 이후의 최신 어플리케이션 개발 환경에서는 웹팩, 롤업 같은 모듈 번들러를 사용한다. 이러한 도구로 번들링 작업을 수행할 때, 사용하지 않는 코드는 자동으로 삭제된다. CommonJS 모듈은 트리쉐이킹을 지원하지 않지만 ES6 이후에는 파일 내 특정 모듈만 임포트하면 해당 모듈을 사용하지 않는 파일 코드는 삭제되어 더 작은 크기의 번들링 파일을 생성할 수 있게 되었다

📍 타입을 확인하는 방법

  • typeof, instanceof, 타입 단언을 사용해 타입을 확인할 수 있음

  • typeof는 연산하기 전에 피연산자의 데이터 타입을 나타내는 문자열을 반환함 -> typeof 연산자가 반환하는 값은 자바스크립트의 7가지 기본 데이터 타입(Boolean, null, undefined, Number, BigInt, String, Symobl)과 Function(함수), 호스트 객체, object객체가 될 수 있음

    typeof 2022; // number
    typeof "woowahan"; // string
    typeof ture; // boolean
    typeof {}; // object
  • 타입스크립트에는 값 공간과 타입 공간이 별도로 존재 -> 타입스크립트에서 typeof 연산자도 값에서 쓰일 때와 타입에서 쓰일 때의 역할이 다름

    interface Person {
        first: string;
        last: string;
    }
    
    const person: Person = { first: "zig", las: "song"};
    
    function email(options: { person: Person; subject: string; body: string}) {}
  • 값에서 사용된 typeof 연산자는 자바스크립트 typeof 연산자와 동일하게 해당 타입을 string 형태로 나타냄 (자바스크립트 런타임의 typeof 연산자가 된다)

    const v1 = typeof person; // 값은 'object'
    const v2 = typeof email; // 값은 'function'
    const user = { name: 'lee', age: 20 };
    console.log(typeof user); // 'objcet'
    console.log(typeof user.age); // 'number'
    
  • 타입에서 사용된 typeof는 값을 읽고 타입스크립트 타입을 반환함 (typeof 연산자는 해당 타입스크립트를 반환)

    type T1 = typeof person; // 타입은 Person
    type T2 = typeof email; // 타입은 (options: { person: Person; subject: stirng; body: stirng; }) => void
    const user = { name: 'lee', age: 20 };
    type UserType = typeof user; //  {name: string; age: number}
  • person 변수는 interface Person 타입으로 선언되었기 때문에 타입 공간에서의 typeof person의 Person을 반환한다.

  • email 함수는 타입 공간에서 typeof 연산자로 값을 읽을 때, 함수의 매개변수 타입과 리턴 타입을 포함한 함수 시그니처 타입을 반환한다.

  • v1과 v2는 const 키워드로 선언된 변수로 값이 할당될 공간이다. 값 공간의 typeof는 피연산자인 person과 email의 런타임 타입을 가리키는 문자열을 반환한다 => 값에서 사용된 typeof 연산자는 자바스크립트 typeof 연산자와 동일하게 동작

  • 자바스크립트 클래스는 typeof 연산자를 쓸 때 주의해야 한다. 앞서 선언한 Developer 클래스를 다시보면,

    class Developer {
        name: string;
        sleepingTime: number;
    
        constructor(name: string, sleepingTime: number){
            this.name = name;
            this.sleepingTime = sleepingTime;
        }
    }
    
    const d = typeof Developer; // 값이 'function'
    type T = typeof Developer; // 타입이 typeof Developer
  • 자바스크립트의 클래스는 결국 함수이므로 값 공간에서 typeof Developer의 값은 function

  • 타입 공간에서 typeof Developer의 반환값은 type T에 할당된 Developer는 인스턴스 타입이 아니라 new 키워드를 사용할 때 볼 수 있는 생성자 함수이기 때문

    const zig: Developer = new Developer("zig", 7);
    type ZigType = typeof zig; // 타입이 Developer
  • Developer 클래스로 생성한 zig 인스턴스는 Developer가 인스턴스 타입으로 생성되었기 때문에 타입 공간에서의 typeof zig 즉, type ZigTtype은 Developer를 반환함

  • 그러나 Developer는 Developer 타입의 인스턴스를 만드는 생성자 함수 -> typeof Developer 타입도 그 자체인 typeof Developer가 됨

  • typeof Developer를 풀어서 설명하면,

    new (name: string, sleepingtime: number): Developer
  • 자바스크립트에서 instanceof 연산자를 사용하면 프로토타입 체이닝 어딘가에 생성자의 프로토타입 속성이 존재하는지 판단할 수 있음 -> typeof 연산자처럼 istanceof 연산자의 필터링으로 타입이 보장된 상태에서 안전하게 값의 타입을 정제하여 사용할 수 있음

    let error = unknown;
    
    if(error instanceof Error) {
        showAlertModal(error.message);
    } else {
        throw Error(error);
    }
  • 타입스크립트에서는 타입 단언이라 부르는 문법을 사용해 타입을 강제할 수도 있음 : as 키워드 사용

  • 타입 단언은 개발자가 해당 값의 타입을 더 잘 파악할 수 있을 때 사용되며 강제 형 변환과 유사한 기능을 제공함
    *다른 언어의 타입 캐스팅과 타입스크립트의 타입 단언은 유사한 부분도 있지만 일치하는 개념은 아님. 결국 타입스크립트 코드는 자바스크립트 코드로 변환되고 타입스크립트의 타입 시스템과 문법은 컴파일 단계에서 제거됨. 따라서 컴파일 단계에서는 타입 단언이 형 변환을 강제할 수 있지만 런타임에서는 효력을 발휘하진 못함.

    const loaded_text: unknown; // 어딘가에서 unknown 타입 값을 전달받았다고 가정
    const validateInputText = (text: string) => {
        if (text.length < 10) return "최소 10글자 이상 입력해야 합니다.";
        return "정상 입력된 값입니다.";
    };
    
    validateInputText(loaded_text as string); 
    // as 키워드를 사용해서 string으로 강제하지 않으면 타입스크립트 컴파일 단계에서 에러 발생
  • 이외에도 타입을 검사하는 다른 방법인 타입 가드라는 패턴도 있음 (타입 가드는 특정 조건을 검사해서 타입을 정제하고 타입 안정성을 높이는 패턴임)

💡 원시 타입

  • 타입스크립트는 자바스크립트의 슈퍼셋이므로 자바스크립트와 대응되는 부분이 많지만 차이점도 있음
  • 자바스크립트에서 값은 타입을 가지지만 변수는 별도의 타입을 가지지 않음 -> 자바스크립트의 변수에는 어떤 타입의 값이라도 자유롭게 할당할 수 있음
  • 타입스크립트는 이 변수에 타입을 지정할 수 있는 타입 시스템 체계를 구축함 -> 특정 타입을 지정한 변수에 해당 타입의 값만 할당할 수 있는 식임
  • 자바스크립트의 7가지 원시 값은 타입스크립트에서 원시 타입으로 존재함

*원시 값과 원시 래퍼 객체: 자바스크립트의 내장 타입을 파스칼 표기법으로 표기했는데, 타입스크립트에서는 이에 대응하는 타입을 소문자로 표기한다. 자바스크립트는 컴파일 시점에 타입스크립트의 타입 시스템이 적용되지 않으므로 타입스크립트와 구별하기 위해 소문자로 표기하지 않았다. 타입을 파스칼 표기법으로 표기하면 자바스크립트에서는 이것을 원시 래퍼 객체라고 부른다. null과 undefined를 제외한 모든 원시 값은 해당 원시 값을 래핑한 객체를 가진다.
원시 래퍼 객체는 이름에서 알 수 있듯이 원시 값이 아닌 객체라는 점에 주의하자. 따라서 타입스크립트에서는 내장 원시 타입에 해당하는 타입을 파스칼 표기법으로 쓰지 않도록 주의해야 한다. 타입스크립트에도 원시 래퍼 객체가 존재하는데 이것은 고유한 타입으로 분류되기 때문에 둘은 엄연히 다르다.

📍 boolean

const isEmpty: boolean = true;
const isLoading: boolean = false;

// errorAction.type과 ERROR_TEXT가 같은지 비교한 결괏값을 boolean 타입으로 반환하는 함수
function isTextError(errorCode: ErrorCodeType): boolean {
	const errorAction = getErrorAction(errorCode);
    if(errorAction) {
    	return errorAction.type === ERROR_TEXT;
    }
    return false;
}
  • 오직 true와 false 값만 할당할 수 있는 boolean 타입
  • 자바스크립트에는 boolean 원시 값은 아니지만 형 변환을 통해 true / false로 취급되는 Truthy / Falsy 값이 존재함 but 이 값은 boolean 원시 값이 아니므로 타입스크립트에서도 boolean 타입에 해당하지 않음

📍 undefined

let value: string;
console.log(value); // undefined (값이 아직 할당되지 않음)

type Person = {
	name: string;
    job?: string;
};
  • 정의되지 않았다는 의미의 타입. 오직 undefined 값만 할당할 수 있음
  • 일반적으로 초기화 되지 않은 값을 의미하고, 변수 선언만 하고 값을 할당하지 않을때 undefined가 반환됨
  • Person 타입의 job 속성은 옵셔널로 지정되어 있는데, 이런 경우에도 undefined를 할당할 수 있음
  • 초기화 되어 있지 않거나 존재하지 않음을 나타냄

📍 null

let value: null | undefined;
console.log(value); // undefined(값이 아직 할당되지 않음)

value = null;
console.log(value); // null
  • 오직 null만 할당할 수 있음
  • 자바스크립트에서 보통 빈 값을 할당해야 할 때 사용 -> 이때 사용된 null은 명시적, 의도적으로 값이 아직 비어있음을 수 있음을 보여줌
  • 자바스크립트에서 흔히 값이 없다는 것을 나타날때 null과 undefined를 혼용함 (동등 연산자(==)로 둘을 비교하면 서로 동등하다는 결과인 true 값을 볼 수 있음)
  • null과 undefined이 비슷해보여도 엄연히 따로 존재하는 원시 값이므로 서로의 타입에 할당할 수 없음
type Person1 = {
	name: string;
    job?: string;
}

type Person2 = {
	name: string;
    job: string | null;
}
  • 모든 사람이 이름과 직업을 가진다고 가정할때, 사람마다 현업에 종사하고 있을 수도 있고 무직일 수 있다. Person1은 job이라는 속성이 있을 수도 없을 수도 있음을 나타냄 (=job이라는 속성 유무를 통해 무직인지 아닌지를 나타냄)
  • Person2는 job이라는 속성을 사람마다 갖고 있지만 값이 비어있을 수도 있다는 것을 나타냄 (=명시적인 null 값을 할당해 무직인 상태를 나타낸다고 볼 수 있음)

📍 number

const maxLegnth: number = 10;
const maxWidth: number = 120.3;
const maximum: number = +Infinity;
const notANumber: number = NaN;
  • 자바스크립트의 숫자에 해당하는 모든 원시 값을 할당할 수 있음
  • 자바 같은 언어에서는 byte.short.int.long.double.float 등 다양한 숫자 타입으로 구분되어 있는 것과 달리 자바스크립트의 숫자는 정수, 부동소수점수를 구분하지 않아서 모두 number 타입에 할당할 수 있음
  • 자바스크립트에서 숫자에 해당하는 원시 값 중 NaN(숫자가 아님)이나 Infinity(무한대를 나타내는 숫자형 값)도 포함

📍 bigInt

const bigNumber1: bigint = BigInt(999999999999);
cosnt bigNumber2: bigInt = 99999999999;
  • ES2020에서 새로 도입된 데이터 타입으로 타입스크립트 3.2 버전부터 사용 가능
  • 이전의 자바스크립트에서는 가장 큰 수인 Number.MAX_SAFE_INTEGER(2^53-1)를 넘어가는 값을 처리할 수 없었는데 bigInt를 사용하면 이보다 큰 수 처리할 수 있음
  • number 타입과 bigInt 타입은 엄연히 서로 다른 타입이므로 상호작용 불가능

📍string

const receiverName: string = "kg";
const receiverPhoneNumber: string = "010-0000-0000";
const letterContent: string = `안녕, 내이름은 ${senderName}이야.`;
  • 문자열을 할당할 수 있는 타입
  • 공백도 string 타입에 해당함
  • 작은 따옴표(')나 큰 따옴표(")로 둘러싼 문자열 말고도 백틱(`)으로 감싼 문자열 내부에 변숫값을 포함할 수 있는 템플릿 리터럴 문법도 있음

📍 symbol

const MOVIE_TITLE = Symbol("title");
const MUSIC_TITLE = Symbol("title");
console.log(MOVIE_TITLE === MUSIC_TITLE); // false

let SYMBOL: unique symbol = Symbol(); // A variable whose type is a 'unique symbol' type must be 'const'
  • ES2015에서 도입된 데이터 타입
  • Symbol() 함수를 사용하면 어떤 값과도 중복되지 않는 유일한 값을 생성할 수 있음
  • 예시처럼 "title"이라는 동일한 문자열을 넘겨줬을 때도 서로 다른 값을 가지고 있음을 알 수 있음
  • 타입스크립트에는 symbol 타입과 const 선언에서만 사용할 수 있는 unique symbol 타입이라는 symbol의 하위 타입도 있음

number, string, boolean은 가장 대표적인 3가지 원시 타입이자 다른 타입을 구성하는 기본 원소 같은 타입으로 가장 많이 사용된다. 따라서 사용자에 따라 다르게 사용될 여지가 적다. 반면, null이나 undefined는 tsconfig 옵션이나 사용자 취향에 따라 다르게 사용될 여지가 있다.

타입스크립트의 모든 타입은 기본적으로 null과 undefined를 포함하고 있다. 하지만 tsconfig의 strictNullChecks 옵션을 활성화했을 때는 사용자가 명시적으로 해당 타입에 null 이나 undefined를 포함해야만 null과 undefined를 사용할 수 있다. 그렇지 않으면 null과 undefined가 될 수 있는 경우에 타입스크립트 에러가 발생하는데 보통 타입 가드로 null과 undefined가 되는 경우를 걸러낸다.
!연산자를 사용해 타입을 단언하는 방법도 있다.

이를 통해 사용자는 해당 참조가 null이나 undefined가 아니라고 보장할 수 있는데, 일반적으로 타입 가드를 사용하는 것이 더 안전하다고 여겨져 단언문보다 타입 가드가 좀더 선호되는 경향이 있다.

💡 객체 타입

  • 7가지 원시 타입에 속하지 않는 값은 모두 객체 타입으로 분류할 수 있음
  • 자바스크립트에서 객체의 범주는 원시 타입에 비해 굉장히 넓음 -> 자바스크립트에서는 이런 값을 모두 객체로 일컫는데 타입슼릡트에서는 다양한 형태를 가지는 객체마다 개별적으로 타입을 지정할수 있음
  • 예를 들어 배열 또는 클래스를 타입으로 지정할 수 있으며 매우 복잡한 구조를 가진 객체도 타입으로 만들어 관리할 수 있음

📍 object

  • 자바스크립트 객체의 정의에 맞게 대응하는 타입스크립트 타입 시스템은 object 타입
  • object 타입은 가급적 사용하지 말도록 권장되는데, any 타입과 유사하게 객체에 해당하는 모든 타입 값을 유동적으로 할당할 수 있어 정적 타이핑의 의미가 퇴색됨 (any 타입과는 다르게 앞서 다룬 원시 타입에 해당하는 값은 object 타입에 속하진 않음)
function isObject(value: object) {
	return(
    	Object.prototype.toString.call(value).replace(/\[|\]|\s|object/g, "") === "Object");
}

// 객체, 배열, 정규 표현식, 함수, 클래스 등 모두 obejct 타입과 호환됨
isObject({});
isObject({ name: "KG" });
isObject([0, 1, 2]);
isObject(new RegExp("object"));
isObject(functon () {
	console.log("hello world");
});
isObject(class Class {});

// 그러나 원시 타입은 호환되지 않음
isObject(20); // false
isObject("KG"); // false

📍 {}

  • 중괄호 {}는 자바스크립트에서 객체 리터럴 방식으로 객체를 생성할 때 사용
  • 타입스크립트에서 객체를 타이핑할 때도 중괄호를 쓸 수 있는데, 중괄호 안에 객체의 속성 타입을 지정해주는 식으로 사용 -> 이것은 타이핑 되는 객체가 중괄호 안에서 선언된 구조와 일치해야 한다는 것을 말함!
// 정상
const noticePopup: { title: string; description: string } = {
	title: "IE 지원 종료 안내",
    description: "2022.07.15일부로 배민상회 IE 브라우저 지원을 종료합니다.",
};

// SyntaxError
const noticePopup: { title: string; description: string } = {
	title: "IE 지원 종료 안내",
    description: "2022.07.15일부로 배민상회 IE 브라우저 지원을 종료합니다.",
    startAt: "2022.07.15 10:00:00", // startAt은 지정한 타입에 존재하지 않으므로 오류
};
  • 자바스크립트에서 빈 객체를 생성하기 위해 const obj = {};와 같은 구문을 사용할 수 있는데, 타입스크립트 역시 이에 대응하는 타입으로 {}를 사용할 수 있고, 자바스크립트와 마찬가지로 빈 객체임을 의미
  • {} 타입으로 지정된 객체에는 어떤 값도 속성으로 할당할 수 없음
  • 빈 객체 타입을 지정하기 위해서는 {}보다 유틸리티 타입으로 Record<string, never>처럼 사용하는게 바람직
let noticePopup: {} = {};
noticePopup.title = "IE 지원 종료 안내"; // (X) title 속성을 지정할 수 없음
  • {} 타입으로 지정된 객체는 완전히 비어있는 순수한 객체를 의미하는 것이 아님
  • 자바스크립트 프로토타입 체이닝으로 Object 객체 레퍼에서 제공하는 속성에는 정상적으로 접근할 수 있음
  • 타입스크립트에서 객체 래퍼를 타입으로 지정할 수 있는데도 이러한 이유 때문에 소문자로 된 타입스크립트 타입 체계를 사용하는게 일반적
console.log(noticePopup.toString()); // [object Object]

📍 array

  • 타입스크립트는 자바스크립트 객체를 세분화해서 타입을 지정할 수 있는 타입 시스템을 갖음

  • 자바스크립트에서는 흔히 사용하는 객체 자료구조 외에 배열, 함수, 정규식 등이 객체 범주에 속함

  • 타입스크립트에서는 이런 각각의 객체에 타입을 지정할 수 있음

  • 자바스크립트의 배열 자료구조는 원소를 자유롭게 추가하고 제거할 수 있으며 타입 제한 없이 다양한 값을 다룸 -> 하나의 배열 안에 숫자, 문자열과 같은 서로 다른 값이 혼재될 수 있음 -> 이러한 쓰임은 타입스크립트가 추구하는 정적 타이핑 방향과 맞지 않음

  • 타입스크립트에서는 배열을 array라는 별도 타입으로 다룸

  • 타입스크립트 배열 타입은 하나의 타입 값만 가질 수 있다는 점에서 자바스크립트 배열보다 조금 더 엄격함 but 자바스크립트와 마찬가지로 원소 개수는 타입에 영향 주지 않음

  • 타입스크립트에서 배열 타입을 선언하는 방식은 Array 키워드로 선언하거나 대괄호([])를 사용해서 선언하는 방법이 있음

const getCartList = async (cartId: number[]) => {
	const res = await CartApi.GET_CART_LIST(cartId);
    return res.getData();
};

getCartList([]); // O 빈 배열도 가능
getCartList([1001]); // O
getCartList([1001, 1002, 1003]); // O number 타입 원소 몇 개가 들어와도 상관 없음
getCartList([1001, "1002"]);// X "1002"는 string 타입이므로 불가함
  • 주의해야할점은 튜플 타입도 대괄호로 선언한다는 것

  • 타입스크립트 튜플 타입은 배열과 유사하지만 튜플의 대괄호 내부에는 선언 시점에 지정해준 타입 값만 할당할 수 있음 & 원소 개수도 타입 선언 시점에 미리 정해짐 -> 객체 리터럴에서 선언하지 않은 속성을 할당하거나, 선언한 속성을 할당하지 않을 때 에러가 발생한다는 점과 비슷

const targetCodes: ["CATEGORY", "EXHIBITION"] = ["CATEGORY", "EXHIBITION"]; // O
const targetCodes: ["CATEGORY", "EXHIBITION"] = [
	"CATEGORY",
    "EXHIBITION",
    "SALE"
]; // X SALE은 지정할 수 없음

📍 type과 interface 키워드

  • 타입스크립트 object 타입은 실무에서는 잘 사용하지 않음(자바스크립트와 대응되는 예시를 보여주기 위해 언급한 것이라고함)

  • 객체를 타이핑하기 위해서는 타입스크립트에서만 독자적으로 사용할 수 있는 키워드를 사용하는게 일반적

  • 객체 범주에 속하는 배열도 마찬가지로 타입스크립트에서는 object 대신 오직 배열임을 나타내는 타입스크립트만의 배열 타입 시스템을 사용할 수 있음

  • 흔히 객체를 타이핑 하기 위해 자주 사용하는 키워드로 type과 interface가 있음

  • 중괄호를 사용한 객체 리터럴 방식으로 타입을 매번 일일이 지정하기에는 중복적인 요소가 많음 -> 반복적으로 사용돼도 중복 없이 해당 타입을 쓸 수 있음

type NoticePopupType = {
	title: string;
    description: string;
}

interface INoticePopup {
	title: string;
    description: string;
}

const noticePopup1: NoticePopupType = { ... };
const noticePopup2: INoticePopup = { ... };

타입스크립트에서 일반적으로 변수 타입을 명시적으로 선언하지 않아도 컴파일러가 자동으로 타입을 추론함 -> 타입스크립트 컴파일러가 변수 사용 방식과 할당된 값의 타입을 분석해서 타입을 유추한다는 것을 의미 -> 모든 변수에 타입을 일일이 명시적으로 선언할 필요는 없음 그러나 타입 추론에 대한 다양한 의견이 있음 -> 컴파일러에 타입 추론을 온전히 맡길 것인지 명시적으로 타입을 선언할 것인지는 개인의 취향 또는 팀의 컨벤션에 따라 다를 수 있음

type과 interface를 둘 다 쓸 수 있는 상호아에서 주로 어떤 것을 사용하나요?

A: 정해진 컨벤션이 있는 건 아니지만 대부분의 상황에서 interface를 사용한다. 하지만 간단한 용도로는 type도 사용한다. 만약 컨벤션으로 정한다면 공식 문서에 쓰인 내용을 바탕으로 전역적으로 사용할 때는 interface를, 작은 범위 내에서 한정적으로 사용한다면 type를 써도 되지 않을까 한다.

B: 둘 다 사용하는데 type은 어떤 값에 대한 정의 같이 정적으로 결정되어 있는 것을, interface는 확장될 수 있는 basis를 정의하거나 어떤 object 구성을 설명하는 요소라 생각한다.

C: 필요에 따라 type 정의와 interface 모두 사용한다. 예를 들어 선언 병합이 필요할 때는 interface를 사용하고, computed value를 사용해야 한다면 type 정의를 쓴다.

D: interface의 필요성을 느끼지 못하고 있어서 type 정의를 주로 사용한다. 현재는 아니지만 예전에 디버깅할 때 IDE에서 inteface는 인터페이스 이름만 노출되고, type은 리터럴한 값이 직접 노출되었다. 그래서 type을 사용하면 더 쉽게 타입 추론을 할 수 있어서 선호했다.

팀 내에서 type이나 interface만을 써야하는 상황이 있었나요?

A: 객체 지향적을 코드를 짤 때, 특히 상속하는 경우에 interface를 사용했다. 예를 들어, extends나 implements를 사용할 때.

B: 유니온 타입이나 교차 타입 등 type 정의에서만 쓸 수 있는 기능을 활용할 때 type을 활용했다. interface 키워드는 예를 들어 다이얼로그(Dialog) 컴포넌트를 만들때, 사이즈가 다른 다이얼로그끼리 같은 속성을 공유하는 기준 인터페이스를 정의하고 확장할 때 사용했다.

C: props에 Record 형식을 extends할 때 interface로 선언된 변수를 넣으면 에러가 발생해서 type으로 바꿔 넣은 경험이 있다. 예를 들어 표 컴포넌트를 만들어서 쓸 때, 배열로 되어있는 데이터를 넣으면 피드 이름이 특정되지 않는 경우가 있다. 이럴 때 Record로 선언해서 컴포넌트를 사용했는데 interface처럼 인덱스 키가 따로 설정되지 않으면 오류가 발생했었다.

D: computed value를 써야할 때 type 정의를 사용했다.

📍 function

  • 자바스크립트에서는 함수도 일종의 객체로 간주하지만 typeof 연산자로 함수 타입을 출력하면 자바스크립트는 함수를 function이라는 별도 타입으로 분류한다는 것을 알 수 있음
function add(a, b) {
	return a + b;
}
console.log(typeof add); // 'function'
  • 마찬가지로 타입스크립트에서도 함수를 별도 함수 타입으로 지정할 수 있음
  • 주의해야할 점이 있음
    1. 자바스크립트에서 typeof 연산자로 확인한 function이라는 키워드 자체를 타입으로 사용하지 않음
    1. 함수는 매개변수 목록을 받을 수 있는데 타입스크립트에서는 매개변수도 별도 타입으로 지정해야함
    2. 함수가 반환하는 값이 있다면 반환 값에 대한 타입도 필요함
function add(a: number, b: number): number {
	return a + b;
}
  • 매개변수 a, b에 number 타입이 지정되고, 함수 이름 옆에 콜론과 함께 다시 number 타입으로 반환 값을 지정하고 있음 -> 타입스크립트에서 함수를 작성할 때 매개변수와 반환 값에 대한 타입을 지정하는 문법을 설명

  • 그럼 함수 자체의 타입은 어떻게 지정할 수 있을까? => 호출 시그니처를 정의하는 방식을 사용하면 됨

*호출 시그니처(call signature): 타입스크립트에서 함수 타입을 정의할 때 사용하는 문법. 함수 타입은 해당 함수가 받는 매개변수와 반환하는 값의 타입으로 결정된다. 호출 시그니처는 이러한 함수의 매개변수와 반환 값의 타입을 명시하는 역할을 함

type add = (a: number, b: number) => number;
  • 호출 시그니처는 자바스크립트의 화살표 함수와 맥락이 유사한 것을 알 수 있음
  • 일반적으로 자바스크립트에서는 함수를 작성할 때 function 키워드를 사용해서 작성하거나 화살표 함수 방식으로 작성
  • 반면, 타입스크립트에서 함수 자체의 타입을 명시할 때는 화살표 함수 방식으로만 호출 시그니처를 정의

*React.FC 사용 지양
https://velog.io/@yena1025/FunctionComponent-FC-%EC%82%AC%EC%9A%A9-%EC%A4%84%EC%9D%B4%EA%B8%B0-24jhm0wp#2-%ED%83%80%EC%9E%85%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%EC%A0%9C%EB%84%A4%EB%A6%AD-%EB%AC%B8%EB%B2%95%EC%9D%84-%EC%A7%80%EC%9B%90%ED%95%98%EC%A7%80-%EC%95%8A%EB%8A%94%EB%8B%A4 참조

profile
프론트엔드개발자가 되고 싶어서 열심히 땅굴 파는 자

0개의 댓글