[Next.js] next-intl 자바스크립트 프로젝트에서 다국어 메시지 자동완성 구현하기 (부분 타입스크립트 활용)

2025. 4. 11. 21:30·Front-End/Next

meme-arsenal

 

신규 프로젝트의 다국어 적용을 마치고

기존 프로젝트에도 다국어 적용이 필요한 상황이었습니다.

하지만 문제는 기존 프로젝트는 자바스크립트 프로젝트라는 것입니다.

사라져버린 다국어 메시지 자동완성

 

신규 프로젝트는 타입스크립트로 진행했기 때문에

어려움 없이 자동완성의 혜택을 누릴 수 있었지만,

자바스크립트 프로젝트에서는 다국어 메시지 자동완성이 불가능했습니다.

 

자동완성 없이 다국어 메시지를 적용한다고? 🤔

 

이건 여러모로 좋지 않을 것 같아서

방법을 찾아봤습니다.

 

결론부터 말하면 부분적 타입스크립트 도입 + JSDoc을 활용해서

다국어 메시지의 자동완성을 구현했던 건에 대해서 소개하겠습니다. 😀

 


📝 JavaScript 프로젝트에서 .d.ts 파일 생성하기

 

⦁1. 타입스크립트를 devDependencies로 설치

yarn add -D typescript

.d.ts 파일을 생성하기 위해선 타입스크립트를 설치해야 합니다. 

-D는 --dev의 줄임말로, 개발에만 필요한 패키지를 설치할 때 사용합니다.

typescript는 우리가 작성한 JS 코드에 타입 자동완성을 위한 도구일 뿐, 실제 빌드나 배포에는 포함되지 않습니다.

 

 

⦁2. .d.ts 파일이란?

- 코드의 구현 없이 타입만 정의되어 있습니다.
- JS 파일에서도 사용할 수 있어, 자동완성과 타입 체크를 가능하게 해줍니다.
- 특히 다국어 JSON 메시지 같은 구조화된 데이터를 다룰 때, 키 자동완성에 매우 유용합니다.

.d.ts 파일은 타입스크립트의 타입 선언 파일(declaration file) 입니다.

저희는 i18n.d.ts 파일을 생성해서, 다국어 메시지 자동완성을 구현할 거예요

JS 프로젝트에서 프로젝트 전체를 TS로 마이그레이션 하지 않아도 부분적으로 타입의 혜택을 누릴 수 있습니다.

 

 

⦁3. jsconfig는 그대로 유지하세요!

 타입스크립트를 설치했다고 해서, jsconfig.json을 tsconfig.json으로 변경할 필요는 없습니다.

오히려 JS 기반 프로젝트라면 tsconfig.json으로 전환하면 에러가 너무 많이 생기고, 설정의 충돌이 발생할 수 있습니다. 

따라서 jsconfig를 유지한 채 타입 보강만 하는 것을 추천드립니다.

 

// jsconfig.json

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "checkJs": true, // 이거랑
    "resolveJsonModule": true // 이거만 추가해주세요
  },
  "include": ["src"]
}

2가지 옵션 정도는 추가해 주셔야 합니다.

- checkJs : JSDoc 사용하기 위함

- resolveJsonModule : JSON 파일을 import 하기 위해 필요 (다국어 메시지는 JSON이니까요)

 


📝 필요한 파일 생성

✅ next-intl을 세팅했다면 위와 같이 i18n 폴더에 파일들이 있을 겁니다.

** 3월 12일에 @4버전으로 올라가면서 라우팅 관련 래핑 컴포넌트를 export 하는 곳이

navigation으로 분리되었습니다. 참고하세요 !

 

⦁1.  i18n.d.ts

// i18n.d.ts

import en from '../../messages/en.json';

type Messages = typeof en;

/* 중첩 객체 자동 완성을 위한 코드 */
type NestedKeyOf<T> = {
  [K in keyof T & string]: T[K] extends object
    ? `${K}.${NestedKeyOf<T[K]>}`
    : K;
}[keyof T & string];

declare global {
  type TKey = NestedKeyOf<Messages>;
}

타입스크립트 프로젝트에서는, 메시지의 typeof만 넘겼을 때에도 정상적으로 자동완성이 되었지만,

자바스크립트 프로젝트에서는 NestedKeyOf 처럼 타입을 만들어줘야 자동완성을 사용할 수 있더라고요.

 

⦁2. useT() 커스텀 훅 생성

/**
 * @typedef {import('./i18n').TKey} TKey
 */
import { useTranslations } from 'next-intl';

/**
 * @returns {(key: TKey) => string}
 */
export function useT() {
  const t = useTranslations();

  /**
   * @param {TKey} key
   */
  return function (key) {
    return t(key);
  };
}

useTranslations을 래핑한 커스텀 훅을 생성합니다.

JSDoc를 사용해서 JS에서도 타입 추론과 자동 완성을 제공합니다! 😎

 

⦁3. 사용해보기

import { useT } from '@/i18n/useT';

function Home() {
  const t = useT();
  
  ...
  
  {t('Common.action')}

 

JS 프로젝트에서 다국어 메시지 자동완성 구현하기 끝 ! 🥳


 

+ 4/15 추가

JSDoc을 사용해 타입을 정의했을 때, 타입 추론 속도가 느린지 자동완성이 불안정한 문제가 발생했습니다. 🥲
결국 useT() 훅을 JSDoc 대신 TypeScript로 전환하여 문제를 해결했습니다.

JSDoc 써보고 싶었는데 아쉽네요

// 1. i18n.d.ts 파일 제거
// 2. useT.js -> useT.ts 타입스크립트로 변환 및 타입 직접 사용

// useT.ts
import { useTranslations } from 'next-intl';
import en from '../../messages/en.json';

/* 다국어 메세지 타입 정의 */
type Messages = typeof en;

type NestedKeyOf<T> = {
  [K in keyof T & string]: T[K] extends object
    ? `${K}.${NestedKeyOf<T[K]>}`
    : K;
}[keyof T & string];

type TKey = NestedKeyOf<Messages>;

/* useTranslations 래핑 커스텀 훅 */
export function useT() {
  const t = useTranslations();

  return (key: TKey): string => t(key);
}

 


📝 마치면서

 

프로젝트 전체를 타입스크립트로 마이그레이션할 수 있으면

좋겠지만, 현실적으로 쉽지 않은 상황이 있을 수 있습니다.

사내 신규 프로젝트에 타입스크립트를 도입하길 정말 다행인 것 같습니다.

 

이럴 땐 이 방법처럼 부분적으로만

타입스크립트를 적용하는 것도 좋은 방법인 것 같습니다. 😀

 


참고 문헌 : 

 

'Front-End > Next' 카테고리의 다른 글

[Next.js] 구글 스프레드시트로 i18n 메시지 관리하기 (Apps Script json 추출)  (0) 2025.03.13
[Next.js] Next 15 국제화라이브러리 비교 + 적용하기 (i18n, next-intl)  (2) 2025.02.24
[Next.js] 넥스트 빌드파일 html id="__next_error__" 해결방법 (useSearchParams)  (0) 2025.01.21
[Next.js] TypeError: jsxDEV is not a function 해결 방법 (캐시 에러)  (3) 2024.10.07
'Front-End/Next' 카테고리의 다른 글
  • [Next.js] 구글 스프레드시트로 i18n 메시지 관리하기 (Apps Script json 추출)
  • [Next.js] Next 15 국제화라이브러리 비교 + 적용하기 (i18n, next-intl)
  • [Next.js] 넥스트 빌드파일 html id="__next_error__" 해결방법 (useSearchParams)
  • [Next.js] TypeError: jsxDEV is not a function 해결 방법 (캐시 에러)
현기
현기
  • 현기
    현기의 개발블로그
    현기
  • 전체
    오늘
    어제
    • 분류 전체보기 (120)
      • Front-End (39)
        • Next (5)
        • React (8)
        • React Native (11)
        • Flutter (0)
        • Vue (1)
        • JSP (9)
        • HTML, CSS, JS (5)
      • Back-End (16)
        • Node.js (3)
        • Spring (8)
        • Flask (1)
        • AWS (4)
      • DB (5)
        • Oracle (4)
        • MySQL (1)
      • Python (7)
      • Java (27)
        • 자바 이론 (17)
        • 코딩테스트 연습 & 실습 (10)
      • 자료구조 & 알고리즘 (7)
        • 코딩테스트 (6)
        • 알고리즘 (1)
      • 블록체인 (0)
      • 프롬프트 엔지니어링 (0)
      • CS 지식 (5)
      • IT뉴스 (0)
      • 일상 (3)
      • etc (11)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    REST API
    JSP
    Python
    Java
    react
    자바스크립트
    React Native Chart
    next-intl
    포스트맨
    자바 스프링
    Spring
    파이썬
    상속
    스택
    IS-A
    오블완
    JDBC
    DI
    Express
    자바
    쓰레드
    서블릿
    리액트 네이티브
    react-native-chart-kit
    node.js
    큐
    오라클
    React Native
    그리디
    티스토리챌린지
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
현기
[Next.js] next-intl 자바스크립트 프로젝트에서 다국어 메시지 자동완성 구현하기 (부분 타입스크립트 활용)
상단으로

티스토리툴바