TypeScript (2/3)

thisisyjin·2023년 10월 22일
0

TIL 📝

목록 보기
90/113

TypeScript (2/3)

10-(9) interface, type

interface

  • extends를 이용하여 확장 (객체 타입처럼)
  • interface Interface { name: string; }
  • 선언 병합 가능 (여러 번 선언 시 계속해서 합쳐짐)

type

  • intersection을 이용하여 확장
  • type Type = { name: string; }
  • 선언 병합 불가 (에러 발생)

10-(10) 호출 시그니처, 인덱스 시그니처

Call Signature

interface getNumber {
(like: number): number;
}

interface Post {
id: number;
title: string;
getNumber: getNumber;
// getNumber: (like: number) => number
}
  • 재사용하기 위해 호출 시그니처 이용.
  • 괄호() 안에 args를 넣어주고, : 뒤에 리턴 타입 적어줌

객체 인덱스 시그니처

  • 객체 property로 어떤 것이 추가될지 모르는 경우
  • 객체 인덱스 시그니처를 주면 된다.
interface Post {
[key: string]: unknown;
id: number;
title: string;
}
  • 배열에서도 마찬가지로 사용
  • 배열은 프로퍼티가 NUMBER인 객체이므로 item은 number 타입이 된다.
interface Names {
[item: number]: string;
}

names:Names = ['Kim', 'Lee']

10-(11) 함수 오버로딩

  • 기본적인 구조는 같으나, 매개변수의 타입이 다를 경우
  • 타입 선언을 오버로딩하기
  • 함수 선언 부분과 함수 구현 부분으로 나누어짐
function add(a:string, b:string): string;
function add(a:number, b:number): number;

function add(a:any, b:any): any {
return a+b;
}
  • 함수 오버로딩 예시
// 함수 선언부
function sayWord(word: string): string
function sayWord(words: string[]): string

// 함수 구현부
function sayWord(word:any): any {
if (typeof word === "string") {
return word;
} else if (Array.isArray(word)) {
return word.join(" ");
}
throw new Error("word Error");
}

sayWord(['hello', 'world']);

10-(12) 접근제어자

  • class 에서 this로 접근 시, 클래스 내부에 해당 속성의 타입을 적어줘야 함.
class Post {
constructor(id: number, name: string) {
this.id = id; // error
this.name = name; // error
}
}
  • 클래스 내에 id, name의 타입을 적어주어야 함.
class Post {
public id: number = 0;
public name: string = "";
constructor(id: number, name: string) {
this.id = id;
this.name = name;
}
}

public 과 같은 접근 제어자와 함께 사용.

  1. public
  • default 값. 어디서든 접근 가능
  1. protected
  • 클래스 내 상속받은(extends) 자식 클래스에서 접근 가능
  1. private
  • 클래스 내에서만 접근 가능

constructor 내 접근제어자

  • 위 코드는 id, title이 여러개가 있어 복잡하므로
  • constructor 내에도 접근제어자를 이용하여 타입을 지정해줄 수 있음
class Post {
constructor(private id: number, protected name: string) {
}
}

10-(13) Generic

function getArrLength (arr: number[]): number {
return arr.length;
}

const arr1 = [1,2,3];
const arr2 = ['a','b','c'];
const arr3 = [true, false, true];
  • getArrLength라는 함수에서 arr1, arr2, arr3 모두를 매개변수로 사용하고 싶다면?
    -> 아래와 같이 일일히 타입을 Union(or 기호)로 추가해주어야 한다.
function getArrLength (arr: number[] | string[] | boolean[]): number {
return arr.length;
}
  • 이렇게 되면 매번 새로운 유니언으로 넣어줘야 하기 때문에 불편하다.

Generic

1. 제네릭 일반적인 사용법

  • 어떤 타입이 들어갈지 불분명한 경우
  • 함수 선언부에는 <T> 를 적어주고
  • 해당 함수 호출부에<> 사이에 타입을 적어주면 된다.
function getArrLength<T>(arr:T[]):number {
return arr.length;
}

getArrLength<number>([1,2,3]);
getArrLength<string>(['a','b','c']);
getArrLength<boolean>([true, false]);

2. 객체 extends 사용

const makeName = (obj: {firstName: string, lastname: string}) => {
  return {
    ...obj,
    fullName: obj.firstName + " " + obj.lastName
  }
}

makeFullName({firstName: "Tom", lastName: "Doe", location: "Seoul"}); // Error (location 정의 X)
// obj.loaction을 추가로 넣어줄 수 있도록 할 때 Generic 사용 가능
const makeName = <T extends {firstName: string, lastname: string}>(obj: T) => {
  return {
    ...obj,
    fullName: obj.firstName + " " + obj.lastName
  }
}
  • extends 키워드를 사용하여 해당 프로퍼티를 포함해 +a로 새로운 프로퍼티 전달 가능함.

3. React에서의 Generic

import React from 'react';

interface Props {
  name: string;
}

const ReactComponent: React.FC<Props> = ({ name }) => {
  return <div>{name}</div>;
}

profile
기억은 한계가 있지만, 기록은 한계가 없다.

0개의 댓글