구글링으로 찾은 TypeScript 초보자를 위한 안전한 스토리지 래퍼 활용법

구글링으로 찾은 TypeScript 초보자를 위한 안전한 스토리지 래퍼 활용법

 

TypeScript는 JavaScript에 정적 타입을 더한 언어로, 코드의 안정성과 가독성을 높여주는 강력한 도구입니다.

 

최근 구글링을 통해 Type-Safe Storage Wrapper를 발견하게 되었습니다.

 

이 글에서는 제가 찾은 이 유용한 도구를 TypeScript 초보자 분들도 쉽게 이해하고 활용할 수 있도록 설명드리려고 합니다.

예상 독자

  • TypeScript를 막 배우기 시작한 분
  • JavaScript의 웹 스토리지(localStorage, sessionStorage) 사용 시 타입 안전성을 높이고 싶은 분
  • 기본적인 TypeScript 문법과 제네릭에 대한 이해가 있는 분

Web Storage란?

Web Storage는 브라우저에서 데이터를 저장할 수 있는 방법 중 하나로, localStoragesessionStorage가 대표적입니다.

localStorage는 브라우저를 닫아도 데이터가 유지되지만, sessionStorage는 브라우저를 닫으면 데이터가 사라집니다.

 

하지만 Web Storage의 큰 단점은 저장할 수 있는 데이터가 문자열(String) 형태로만 제한된다는 점인데요.

 

그래서 객체나 숫자 같은 다른 타입의 데이터를 저장하려면 추가적인 처리가 필요합니다.

 

Type-Safe한 Storage 래퍼란?

Type-Safe한 Storage 래퍼는 Web Storage를 사용할 때 발생할 수 있는 타입 관련 문제를 해결해주는 도구입니다.

 

예를 들어, 객체를 저장할 때 문자열로 변환하고 다시 객체로 복원하는 과정을 자동화하고, 타입을 안전하게 관리할 수 있도록 도와줍니다.

 

기본적인 문제점 해결하기

먼저, Web Storage에 객체를 저장하고 불러오는 기본적인 방법을 살펴보겠습니다.

type Person = { name: string, age: number };

const p = { name: "jiftechnify", age: 27 };
localStorage.setItem("item", JSON.stringify(p));

const json = localStorage.getItem("item");
const p2 = JSON.parse(json) as Person;

 

위 코드에서 JSON.stringify는 객체를 문자열로 변환하고, JSON.parse는 문자열을 다시 객체로 복원합니다.

 

하지만 몇 가지 문제가 있습니다.

  1. 타입 단언(as Person)이 필요하다: JSON.parseany 타입을 반환하기 때문에, 원하는 타입으로 직접 변환해야 합니다.
  2. 오류 발생 가능성: 저장된 데이터가 올바른 형식이 아닐 경우, 예기치 않은 오류가 발생할 수 있습니다.

이러한 문제를 해결하기 위해 타입 안전한 Storage 래퍼를 만들어보겠습니다.

 

Type-Safe한 Storage 래퍼 구현하기

Type-Safe한 Storage 래퍼를 구현하기 위해 몇 가지 단계를 거쳐야 합니다.

  1. Codec 인터페이스 정의하기: 데이터를 문자열로 변환하고 다시 복원하는 방법을 정의합니다.
  2. Storage 래퍼 클래스 만들기: setget 메서드를 통해 데이터를 저장하고 불러옵니다.
  3. 타입 매핑 설정하기: 각 키에 어떤 타입의 데이터가 저장될지 정의합니다.
1. Codec 인터페이스 정의하기
export interface Codec<T> {
  encode: (t: T) => string;
  decode: (s: string) => T;
}

 

Codec은 특정 타입의 데이터를 문자열로 변환(encode)하고, 다시 문자열을 원래 타입으로 복원(decode)하는 방법을 정의합니다.

 

2. Storage 래퍼 클래스 만들기
class StorageWrapper<Spec extends Record<string, Codec<any>>> {
  private codecs: Spec;

  constructor(codecs: Spec) {
    this.codecs = codecs;
  }

  set<K extends keyof Spec>(key: K, value: ReturnType<Spec[K]['encode']>): void {
    const codec = this.codecs[key];
    const encodedValue = codec.encode(value);
    localStorage.setItem(key as string, encodedValue);
  }

  get<K extends keyof Spec>(key: K): ReturnType<Spec[K]['decode']> | null {
    const encodedValue = localStorage.getItem(key as string);
    if (encodedValue === null) {
      return null;
    }
    const codec = this.codecs[key];
    return codec.decode(encodedValue);
  }

  remove(key: keyof Spec): void {
    localStorage.removeItem(key as string);
  }
}

 

위 클래스는 setget 메서드를 통해 데이터를 저장하고 불러옵니다.

 

각 메서드는 지정된 타입에 맞게 데이터를 처리합니다.

 

3. 타입 매핑 설정하기
const codecs = {
  person: {
    encode: (p: Person) => JSON.stringify(p),
    decode: (s: string) => JSON.parse(s) as Person,
  },
  age: {
    encode: (n: number) => n.toString(),
    decode: (s: string) => parseInt(s, 10),
  },
};

const storage = new StorageWrapper(codecs);

// 데이터 저장하기
storage.set("person", { name: "Alice", age: 30 });
storage.set("age", 25);

// 데이터 불러오기
const person = storage.get("person");
const age = storage.get("age");

// 데이터 삭제하기
storage.remove("age");

 

위 예제에서 codecs 객체는 각각의 키에 대해 어떤 타입의 데이터를 저장할지 정의하고 있습니다.

StorageWrapper는 이를 바탕으로 데이터를 안전하게 저장하고 불러옵니다.

 

Type-Safe한 Storage 래퍼의 장점

Type-Safe한 Storage 래퍼를 사용하면 다음과 같은 장점이 있습니다.

  1. 타입 오류 방지: 잘못된 타입의 데이터를 저장하거나 불러올 때 컴파일 타임에 오류가 발생하여 안정성을 높여줍니다.
  2. 코드 간결성: 매번 JSON.stringifyJSON.parse를 사용할 필요 없이 간단하게 데이터를 저장하고 불러올 수 있습니다.
  3. 유지보수 용이: 타입 정의가 명확하게 되어 코드의 가독성과 유지보수성이 향상됩니다.

 

결론

 

TypeScript를 사용하면 Web Storage를 더 안전하고 효율적으로 활용할 수 있습니다.

 

Type-Safe한 Storage 래퍼를 구현함으로써, 데이터 저장 및 조회 시 발생할 수 있는 타입 관련 오류를 사전에 방지할 수 있습니다.

 

초보자분들도 이 가이드를 따라 구현해보시면 TypeScript의 타입 시스템을 더욱 잘 이해하고 활용할 수 있게 될 것입니다.

 

앞으로도 TypeScript의 다양한 기능과 활용 방법에 대해 더 많은 글을 작성할 예정이니, 많은 관심 부탁드립니다.