๐Ÿ—‚๏ธ 06. ์„ ์–ธ ํŒŒ์ผ๊ณผ ์„ค์ •: ๋ ˆ๊ฑฐ์‹œ JS๋ฅผ ์šฐ์•„ํ•˜๊ฒŒ ํ’ˆ์–ด๋ผ

2026๋…„ 4์›” 30์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

tsconfig.json์˜ ๋ผˆ๋Œ€์™€ .d.ts๋ฅผ ํ™œ์šฉํ•œ ์ „์—ญ ์Šค์ฝ”ํ”„ ํƒ€์ž… ํ™•์žฅ ๊ธฐ๋ฒ•

๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 10๋ถ„(์ „์ฒด) / ํ•ต์‹ฌ ํŒŒํŠธ๋งŒ: 6๋ถ„

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„
[tsconfig.json์˜ ๋‘ ๊ฐ€์ง€ ํ•ต์‹ฌ ์ถ•] โ†’ [.d.ts์˜ ์กด์žฌ ์ด์œ ] โ†’ [๊ธ€๋กœ๋ฒŒ ๊ณต๊ฐ„ ์นจํˆฌํ•˜๊ธฐ(declare global)]

๐ŸŽฏ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • strict ๋ชจ๋“œ์˜ ์ง„์ •ํ•œ ์˜๋ฏธ๋ฅผ ์ดํ•ดํ•˜๊ณ  ํ”„๋กœ์ ํŠธ ์„ค์ •์˜ ์ด์œ ๋ฅผ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํƒ€๊ฒŸ(Target)๊ณผ ๋ชจ๋“ˆ(Module) ์„ค์ •์ด ์™œ ํ”„๋ก ํŠธ์—”๋“œ ํ™˜๊ฒฝ์—์„œ ๋‚˜๋ˆ ์ง€๋Š”์ง€ ์ดํ•ดํ•œ๋‹ค.
  • ํƒ€์ž… ์ง€์›์ด ์—†๋Š” ์‚ฌ๋‚ด ๊ตฌํ˜• ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์œˆ๋„์šฐ(Window) ๊ฐ์ฒด๋ฅผ ์ž์œ ์ž์žฌ๋กœ ํƒ€์ž… ํ™•์žฅํ•  ์ˆ˜ ์žˆ๋‹ค.

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ๐Ÿฃ ์˜์ฒ  ( ํ”„๋กœ์ ํŠธ ๊ฒฝ๊ณ„๋ฅผ ์ •๋ฆฌํ•˜๋Š” ์ค‘ ): "๋ฆฌ๋“œ ๋‹˜! ํšŒ์‚ฌ์— ์˜ˆ์ „๋ถ€ํ„ฐ ๋‚ด๋ ค์˜ค๋Š” jQuery ๊ธฐ๋ฐ˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์Šคํฌ๋ฆฝํŠธ(youngsoo-magic.js)๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ฐ๋ ค๋Š”๋ฐ, import ํ•˜์ž๋งˆ์ž VScode๊ฐ€ Could not find a declaration file for module ์—๋Ÿฌ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํƒ€์ž…์ด ์—†๋Š” ์ฝ”๋“œ๋„ ํ”„๋กœ์ ํŠธ์— ์•ˆ์ „ํ•˜๊ฒŒ ๋“ค์—ฌ์˜ฌ ๋ฐฉ๋ฒ•์ด ์žˆ์„๊นŒ์š”?"
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "์˜์ฒ  ๋‹˜, ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” importํ•œ ๋ชจ๋“ˆ์˜ ํƒ€์ž… ์„ ์–ธ์„ ์ฐพ์•„์•ผ ์•ˆ์ „ํ•˜๊ฒŒ ๊ฒ€์‚ฌํ•  ์ˆ˜ ์žˆ์–ด์š”. ํƒ€์ž…์ด ์—†๋Š” JS ํŒŒ์ผ์ด๋ผ๋„ ์šฐ๋ฆฌ๊ฐ€ .d.ts๋กœ ์ตœ์†Œ ๊ณ„์•ฝ์„ ์ ์–ด์ค„ ์ˆ˜ ์žˆ์ฃ . ๊ทธ๋ฆฌ๊ณ  ๊ทธ ์„ ์–ธ์„ ์–ด๋””๊นŒ์ง€ ํฌํ•จํ• ์ง€ ์ •ํ•˜๋Š” ๊ธฐ์ค€ํ‘œ๊ฐ€ tsconfig.json์ž…๋‹ˆ๋‹ค. ์˜ค๋Š˜ ๊ทธ ๋‘ ๊ฐ€์ง€ ํ†ต์ œ๊ถŒ์„ ์ฅ์–ด๋ณด์ฃ ."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€: '์„ค์ •'์„ ๋‘๋ ค์›Œํ•˜์ง€ ๋ง๋ผ

๋ณดํ†ต ์ฃผ๋‹ˆ์–ด ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์ž๋“ค์€ npx create-next-app์ด๋‚˜ vite๊ฐ€ ๋งŒ๋“ค์–ด ์ฃผ๋Š” tsconfig.json์„ ๋‹จ ํ•œ ๋ฒˆ๋„ ์—ด์–ด๋ณด์ง€ ์•Š๊ณ  ์‚ด์‚ด ํ”ผํ•ด ๋‹ค๋‹™๋‹ˆ๋‹ค. ๋ฌด์–ธ๊ฐ€ ๊ฑด๋“œ๋ฆฌ๋ฉด ํฐ์ผ ๋‚  ๊ฒƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

ํ•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋‹ค ๋ณด๋ฉด ํ•„์—ฐ์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์œ„๊ธฐ์— ๋ด‰์ฐฉํ•ฉ๋‹ˆ๋‹ค.

  1. "์˜คํ”ˆ์†Œ์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊น”์•˜๋Š”๋ฐ ํƒ€์ž… ์ •์˜๊ฐ€ ์—†๋Œ€..." (npm i @types/xxx ๋„ ์•ˆ ํ†ตํ•จ)
  2. "์ธ๋ผ์ธ ์Šคํฌ๋ฆฝํŠธ๋กœ ๋„ฃ์–ด๋‘” ๊ตฌ๊ธ€ ์• ๋„๋ฆฌํ‹ฑ์Šค ์ „์—ญ ๊ฐ์ฒด window.ga๋ฅผ ์“ฐ๊ณ  ์‹ถ์€๋ฐ TS๊ฐ€ ํ™”๋‚ด..."

์ด๋•Œ ์„ค์ •๊ณผ ์„ ์–ธ ํŒŒ์ผ์˜ ๊ฐœ๋…์„ ๋ชจ๋ฅด๋ฉด, // @ts-ignore ๋‚˜ as any๋กœ ํ˜ธ์ถœ๋ถ€๋งˆ๋‹ค ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ๊บผ๋ฒ„๋ฆฌ๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. 5๋…„ ์ฐจ์˜ ์•„ํ‚คํ…์ฒ˜๋Š” ์ด๋Ÿฐ ์˜ˆ์™ธ๋ฅผ ์ˆจ๊ธฐ๋Š” ๋Œ€์‹ , ํƒ€์ž…์ด ์—†๋Š” ๊ฒฝ๊ณ„์— ํŒ€์ด ๊ณต์œ ํ•  ๊ณ„์•ฝ์„ ๋ถ™์ด๋Š” ๊ฒƒ์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.


โš™๏ธ 1. tsconfig.json์˜ ๋ผˆ๋Œ€ ์ดํ•ดํ•˜๊ธฐ

tsconfig.json ์˜ต์…˜์€ ์ˆ˜์‹ญ ๊ฐœ๊ฐ€ ๋„˜์ง€๋งŒ, ํ˜„์—…์—์„œ ์šฐ๋ฆฌ๊ฐ€ ์ปจํŠธ๋กคํ•ด์•ผ ํ•  ํ•ต์‹ฌ ์ถ•์€ ํฌ๊ฒŒ ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค.

์ถ• A: ์ปดํŒŒ์ผ ํ€„๋ฆฌํ‹ฐ (์—„๊ฒฉํ•จ์˜ ์ •๋„)

{
  "compilerOptions": {
    "strict": true,           // ์‹ ๊ทœ ํ”„๋กœ์ ํŠธ๋ผ๋ฉด ๊ธฐ๋ณธ๊ฐ’์œผ๋กœ ์ผœ๊ณ  ์‹œ์ž‘ํ•˜๊ธฐ
    "noImplicitAny": true,    // "๊ท€์ฐฎ์•„์„œ any๋กœ ๋†”๋‘” ๊ฑฐ ๋‹ค ์žก์•„๋‚ผ ๊ฑฐ์•ผ!"
    "strictNullChecks": true  // "null ์ด๋ž‘ undefined๊ฐ€ ๋“ค์–ด์˜ฌ ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋Šฅ์„ฑ ์ „๋ถ€ ์ฐจ๋‹จํ•ด!"
  }
}

๐Ÿฆ ์˜ํ˜ธ์˜ ๋ฆฌ๋ทฐ ์ฝ”๋ฉ˜ํŠธ: "strict: true๋Š” ์œ„ ์˜ต์…˜๋“ค์„ ๋‹ค ์ผœ์ฃผ๋Š” ์Šค์œ„์น˜์ž…๋‹ˆ๋‹ค. ๊ตฌํ˜• JS ํ”„๋กœ์ ํŠธ๋ฅผ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋Š” ํŠน์ˆ˜ํ•œ ์ƒํ™ฉ์ด ์•„๋‹ˆ๋ผ๋ฉด ์ผœ๊ณ  ์‹œ์ž‘ํ•˜๋Š” ํŽธ์ด ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. ๋А์Šจํ•œ ์„ค์ •์€ ๋‹น์žฅ์€ ํŽธํ•˜์ง€๋งŒ, ๋Ÿฐํƒ€์ž„์—์„œ ํ™•์ธํ•ด์•ผ ํ•  ์ผ์ด ๋Š˜์–ด๋‚ฉ๋‹ˆ๋‹ค."

์ถ• B: ํƒ€๊ฒŸ๊ณผ ํ™˜๊ฒฝ ์„ค์ • (์–ด๋””์„œ ๋Œ๋ฆด ๊ฒƒ์ธ๊ฐ€)

์ด ๋ถ€๋ถ„์ด ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์„ ํ—ท๊ฐˆ๋ฆฌ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

{
  "compilerOptions": {
    // 1. ๋‚ด๊ฐ€ ๋ณ€ํ™˜ํ•  ์ตœ์ข… JS ๋ฌธ๋ฒ• ์ˆ˜์ค€
    "target": "ES6",
 
    // 2. ๋ชจ๋“ˆ ์‹œ์Šคํ…œ์€ ๋ญ˜ ์“ธ ๊ฑด๊ฐ€? (CommonJS vs ESNext)
    "module": "ESNext",
 
    // 3. ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋Œ๋ฆด ๊ฑฐ์•ผ? ๋…ธ๋“œ์—์„œ ๋Œ๋ฆด ๊ฑฐ์•ผ? (์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‚ด์žฅ ๊ฐ์ฒด๋“ค)
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
 
    // ๋ฒˆ๋“ค๋Ÿฌ(Webpack, Webpack, Vite, Next.js ๋“ฑ)๋ฅผ ์“ธ ๋•Œ ํ•„์ˆ˜ ์˜ต์…˜
    "moduleResolution": "bundler",
  }
}

ํ”„๋ก ํŠธ์—”๋“œ(React, Next.js)์—์„œ๋Š” ์‚ฌ์‹ค์ƒ TS ์ปดํŒŒ์ผ๋Ÿฌ(tsc)๊ฐ€ ์‹ค์ œ๋กœ JS๋ฅผ ๋ณ€ํ™˜ํ•˜์—ฌ ๋–จ๊ตฌ๋Š”(emit) ์—ญํ• ์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณ€ํ™˜์€ Babel์ด๋‚˜ SWC, ์—์Šค๋นŒ๋“œ(esbuild)๊ฐ€ ํ›จ์”ฌ ๋นจ๋ฆฌ ํ•ด์น˜์›๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์šฐ๋ฆฌ๋Š” tsconfig.json์„ "VScode์˜ ๋นจ๊ฐ„ ์ค„ ๊ฒ€์‚ฌ๊ธฐ ๊ธฐ์ค€ํ‘œ" ์ •๋„๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋ง˜์ด ํŽธํ•ฉ๋‹ˆ๋‹ค.


๐Ÿ›‚ 2. .d.ts ์„ ์–ธ ํŒŒ์ผ: ํƒ€์ž… ์ „์šฉ ์—ฌ๊ถŒ ๋ฐœ๊ธ‰์†Œ

์˜์ฒ ์ด์˜ ๋”œ๋ ˆ๋งˆ๋กœ ๋Œ์•„๊ฐ€ ๋ด…์‹œ๋‹ค. ๊ตฌํ˜• ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ํƒ€์ž…์ด ์—†์Šต๋‹ˆ๋‹ค.
ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์ž„ํฌํŠธ๋˜๋Š” ๋ชจ๋“ˆ์„ ๋ณผ ๋•Œ ํ•ญ์ƒ ๊ทธ ์˜†์— ์ง๊ฟ์ธ .d.ts (Declaration) ํŒŒ์ผ์ด ์žˆ๋Š”์ง€๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

.d.ts ํŒŒ์ผ์—๋Š” ์‹ค์ œ ๋™์ž‘ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ(๋กœ์ง)๊ฐ€ ๋‹จ ํ•œ ์ค„๋„ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ค๋กœ์ง€ "์—ฌ๊ธฐ ์ด๋Ÿฐ ํ•จ์ˆ˜๋ž‘ ํด๋ž˜์Šค๊ฐ€ ์žˆ์–ด~" ํ•˜๊ณ  ๊ป๋ฐ๊ธฐ๋งŒ ์„ ์–ธ(Declare)ํ•ด ์ฃผ๋Š” ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.

์˜์ฒ ์ด์˜ ๋งˆ์ˆ  ๊ฐ™์€ ํŒŒ์ผ: youngsoo-magic.d.ts

ํ”„๋กœ์ ํŠธ ์ตœ์ƒ๋‹จ types ํด๋”(๋ณดํ†ต tsconfig.json์˜ include์— ๋“ฑ๋ก๋จ)์— ๋นˆ ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ์•„๋ž˜์ฒ˜๋Ÿผ ์จ์ฃผ๋ฉด ์–ด๋ฆฌ๋‘ฅ์ ˆํ•˜๋˜ TS๊ฐ€ ๊ฐ‘์ž๊ธฐ ์–Œ์ „ํ•ด์ง‘๋‹ˆ๋‹ค.

// types/youngsoo-magic.d.ts
 
// ๐Ÿฆ ์˜ํ˜ธ: "์ผ๋‹จ ๊ธ‰ํ•˜๋‹ˆ๊นŒ ์ € ๋ชจ๋“ˆ์ด ์กด์žฌํ•œ๋‹ค๋Š” ๊ฒƒ๋งŒ TSํ•œํ…Œ ์‹ ๊ณ ํ•ฉ์‹œ๋‹ค."
declare module 'youngsoo-magic' {
  // ๋ชจ๋“ˆ ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜๋‚˜ ๊ฐ์ฒด ๋ผˆ๋Œ€๋ฅผ ์—ฌ๊ธฐ์— ๋Œ€์ถฉ์ด๋ผ๋„ ๋ฌ˜์‚ฌํ•ด์ค€๋‹ค.
  export function doMagic(target: string): void;
  export const version: string;
}

์ด์ œ import { doMagic } from 'youngsoo-magic' ์„ ์จ๋„ ์•„๋ฌด ์—๋Ÿฌ๊ฐ€ ๋‚˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์ด์ œ ํ•ด๋‹น ํŒŒ์ผ์— ์ €๋Ÿฐ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฑธ "์„ ์–ธ"๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.


๐ŸŒ 3. ๊ธ€๋กœ๋ฒŒ ์ฐจ์› ์นจํˆฌ: declare global

๊ฐ€์žฅ ์šฐ์•„ํ•˜๊ณ  ๋นˆ๋ฒˆํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ์Šคํ‚ฌ์ž…๋‹ˆ๋‹ค.
๋ธŒ๋ผ์šฐ์ €์— ๋‚ด์žฅ๋œ window ๊ฐ์ฒด์— ์˜์ˆ˜๋„ค ํšŒ์‚ฌ๊ฐ€ ๋งŒ๋“  ์ „์—ญ ํ•จ์ˆ˜ window.KakaoLogin()์„ ๋ถ™์ด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

// ์ผ๋ฐ˜ TS ํŒŒ์ผ
window.KakaoLogin = () => { /* ... */ };
// โŒ ์—๋Ÿฌ: Property 'KakaoLogin' does not exist on type 'Window & typeof globalThis'.

์„ ์–ธ ๋ณ‘ํ•ฉ(Declaration Merging)์˜ ๋ถ€ํ™œ

์šฐ๋ฆฌ๋Š” 2์žฅ(Interface vs Type)์—์„œ interface๋Š” ๋˜‘๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ๋‘ ๋ฒˆ ์„ ์–ธํ•˜๋ฉด ํ•ฉ์ณ์ง„๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฐ์› ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ window ๊ฐ์ฒด์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

// types/global.d.ts
export {}; // ์ด ํŒŒ์ผ์„ ์ „์—ญ ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์•„๋‹Œ ๋ชจ๋“ˆ๋กœ ์ธ์‹์‹œ์ผœ declare global์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋‘”๋‹ค.
 
declare global {
  // Window ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์—ด๊ณ  ๋‚ด ๋ง˜๋Œ€๋กœ ํ™•์žฅ!
  interface Window {
    KakaoLogin: () => void;
    // ์‚ฌ๋‚ด ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๊ฐ™์€ ๊ฒƒ๋„ ์ „์—ญ์œผ๋กœ ๋„ฃ์–ด๋‘˜ ์ˆ˜ ์žˆ๋‹ค.
    YOUNGSOO_ENV: string;
  }
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ”„๋กœ์ ํŠธ ์–ด๋””์—์„œ๋“  window.KakaoLogin()์„ ํ˜ธ์ถœํ•  ๋•Œ ์ž๋™ ์™„์„ฑ์ด ๋œจ๊ณ , ์•ˆ์ „ํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. tsconfig.json์˜ strict: true ์˜ต์…˜์€ ๋ฌด์—‡์„ ์˜๋ฏธํ•˜๋‚˜์š”?

โœ… ์ •๋‹ต: ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์˜ ๊ฐ€์žฅ ์—„๊ฒฉํ•œ ํƒ€์ž… ๊ฒ€์‚ฌ๊ธฐ ์˜ต์…˜๋“ค(noImplicitAny, strictNullChecks ๋“ฑ)์„ ํ•œ๊บผ๋ฒˆ์— ์ผœ์ฃผ๋Š” ๋งˆ์Šคํ„ฐ ์Šค์œ„์น˜์ž…๋‹ˆ๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์ด ์˜ต์…˜์„ ์ผœ์ง€ ์•Š์œผ๋ฉด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์‚ฌ์‹ค์ƒ "ํƒ€์ดํ•‘๋„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ" ์ˆ˜์ค€์˜ ๋А์Šจํ•œ ์–ธ์–ด๋กœ ์ „๋ฝํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ๊ธฐ์น˜ ๋ชปํ•œ ๋Ÿฐํƒ€์ž„ Null ์—๋Ÿฌ๋ฅผ ๋ง‰๋Š” strictNullChecks์˜ ๋ฐฉํŒจ๋ฅผ ์žƒ๊ฒŒ ๋˜๋ฏ€๋กœ, ์‹ ๊ทœ ํ”„๋กœ์ ํŠธ๋ผ๋ฉด ๋ฌด์กฐ๊ฑด true๋กœ ์„ค์ •ํ•˜๊ณ  ์‹œ์ž‘ํ•˜๋Š” ๊ฒƒ์ด 5๋…„ ์ฐจ์˜ ์ฒ ์น™์ž…๋‹ˆ๋‹ค.

Q2. ์ˆœ์ˆ˜ํ•œ .d.ts ์„ ์–ธ ํŒŒ์ผ ์•ˆ์—๋Š” ์–ด๋–ค ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ "์—†๋Š”"๊ฐ€์š”?

โœ… ์ •๋‹ต: ์‹ค์ œ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐ์ž‘ํ•˜๊ฑฐ๋‚˜ ํ•จ์ˆ˜๊ฐ€ ๋™์ž‘ํ•˜๋Š” '๊ตฌํ˜„๋ถ€(Implementation)' ์ฝ”๋“œ๋Š” ์ž‘์„ฑํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. (์˜ˆ: function add(a:number) { return a + 1 } ๊ฐ™์ด ์ค‘๊ด„ํ˜ธ๋กœ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ ๋ถˆ๊ฐ€)

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • .d.ts๋Š” ํƒ€์ž… ์„ ์–ธ ์ „์šฉ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ ๋™์ž‘ํ•˜๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ๋ณ€ํ™˜(Emit)๋˜์ง€ ์•Š๋Š” ํˆฌ๋ช…ํ•œ ํŒŒ์ผ์ž…๋‹ˆ๋‹ค.
  • ์˜ค์ง interface, type, declare module, declare var ๋“ฑ ๋ผˆ๋Œ€(Signature)๋งŒ์„ ์„ ํฌํ•˜๋Š” ์—ญํ• ๋งŒ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Q3. [์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„: ์ „์—ญ ์˜ค์—ผ ๋”œ๋ ˆ๋งˆ] ์˜์ฒ ์ด๊ฐ€ ์ธํ”„๋ผํŒ€์˜ ์š”์ฒญ์œผ๋กœ, ๋ชจ๋ฐ”์ผ ์•ฑ์—์„œ ์›น๋ทฐ(WebView)์— ์ฃผ์ž…ํ•ด์ฃผ๋Š” ๋ธŒ๋ฆฟ์ง€(Bridge) ๊ฐ์ฒด window.AppBridge.close()๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. VScode๋Š” ๊ณ„์† window์— AppBridge๊ฐ€ ์—†๋‹ค๊ณ  ํ™”๋ฅผ ๋‚ด๊ณ , ์˜์ฒ ์ด๋Š” ๋˜ ์ฒด๋…ํ•˜๋ฉฐ (window as any).AppBridge.close()๋ฅผ ์”๋‹ˆ๋‹ค. ํ‡ด๊ทผ ์ „ ์ด ์ฝ”๋“œ๋ฅผ ๋ฆฌ๋ทฐํ•œ ์˜ํ˜ธ ๋ฆฌ๋“œ๋Š” ์–ด๋–ค ํ•ด๋ฒ•์„ ์ œ์‹œํ• ๊นŒ์š”?

โœ… ์ •๋‹ต: global.d.ts ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  declare global { interface Window { AppBridge: { close: () => void } } }๋กœ Window ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ™•์žฅํ•œ๋‹ค.

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: ๋‚ด์žฅ ์ „์—ญ ๊ฐ์ฒด(Window, Document, Array ๋“ฑ)์˜ ํƒ€์ž…์€ TS ์ฝ”์–ด ์„ ์–ธ ํŒŒ์ผ์— ์ด๋ฏธ interface๋กœ ๋“ฑ๋ก๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. 2์žฅ์—์„œ ๋ฐฐ์šด '์„ ์–ธ ๋ณ‘ํ•ฉ' ์›๋ฆฌ์— ๋”ฐ๋ผ, ์šฐ๋ฆฌ๊ฐ€ declare global ์Šค์ฝ”ํ”„ ์•ˆ์—์„œ ๋™์ผํ•œ ์ด๋ฆ„์˜ Window ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋‹ค์‹œ ์„ ์–ธํ•˜๊ณ  ์‚ด์„ ๋ถ™์—ฌ์ฃผ๋ฉด, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์•Œ์•„์„œ ํ•˜๋‚˜๋กœ ํ•ฉ์ณ์ค๋‹ˆ๋‹ค.
  • (window as any)๋Š” ํ˜ธ์ถœ๋ถ€๋งˆ๋‹ค ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ํฌ๊ธฐํ•˜๊ฒŒ ๋งŒ๋“ค์ง€๋งŒ, global.d.ts์˜ ์„ ์–ธ ๋ณ‘ํ•ฉ์€ ํ”„๋กœ์ ํŠธ ์ „์ฒด์— ๊ณตํ†ต ๊ณ„์•ฝ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ํŒŒ์ผ์ด ๋ชจ๋“ˆ๋กœ ์ธ์‹๋˜๋„๋ก export {};๋ฅผ ๋‘๊ณ , ์‹ค์ œ ๊ตฌํ˜„์ด ์•„๋‹ˆ๋ผ ํƒ€์ž… ๊ป๋ฐ๊ธฐ๋งŒ ์„ ์–ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•ต์‹ฌ์€ ์ „์—ญ ๊ฐ์ฒด๋ฅผ "๋ชฐ๋ž˜ ์“ฐ๊ธฐ"๊ฐ€ ์•„๋‹ˆ๋ผ, ํŒ€์ด ๊ณต์œ ํ•˜๋Š” ์„ ์–ธ ํŒŒ์ผ์— ๋ช…์‹œ์ ์ธ ๊ณ„์•ฝ์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜์€ tsconfig.json๊ณผ .d.ts๊ฐ€ ์ˆจ๊ฒจ์ง„ ์„ค์ • ํŒŒ์ผ์ด ์•„๋‹ˆ๋ผ ํŒ€์˜ ํƒ€์ž… ๊ณ„์•ฝ์ด๋ผ๋Š” ๊ฑธ ๋ฐฐ์› ๋‹ค. ํŠนํžˆ ํƒ€์ž… ์—†๋Š” ๋ ˆ๊ฑฐ์‹œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋งŒ๋‚ฌ์„ ๋•Œ @ts-ignore๋กœ ์ง€๋‚˜๊ฐ€๋Š” ๊ฑด ๋‹น์žฅ์˜ ์นจ๋ฌต์ผ ๋ฟ, ๋‹ค์Œ ์‚ฌ๋žŒ์ด ์–ด๋””๊นŒ์ง€ ๋ฏฟ์–ด๋„ ๋˜๋Š”์ง€ ์•Œ ์ˆ˜ ์—†๊ฒŒ ๋งŒ๋“ ๋‹ค.

declare module์€ ๋ชจ๋“ˆ์˜ ์—ฌ๊ถŒ์„ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์ผ์ด๊ณ , declare global์€ ์ „์—ญ ๊ฐ์ฒด์— ํŒ€์ด ํ•ฉ์˜ํ•œ ์†์„ฑ์„ ๋“ฑ๋กํ•˜๋Š” ์ผ์ด๋‹ค. ๋‘˜ ๋‹ค ์‹ค์ œ ๊ตฌํ˜„์„ ๋งŒ๋“œ๋Š” ๊ฒŒ ์•„๋‹ˆ๋ผ, ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋Ÿฐํƒ€์ž„ ์ฝ”๋“œ์˜ ๋ชจ์–‘์„ TS์—๊ฒŒ ์„ค๋ช…ํ•˜๋Š” ์ž‘์—…์ด์—ˆ๋‹ค.

๐Ÿ’ก "์„ ์–ธ ํŒŒ์ผ์€ ๋นจ๊ฐ„ ์ค„์„ ์ˆจ๊ธฐ๋Š” ์ข…์ด๊ฐ€ ์•„๋‹ˆ๋ผ, ํƒ€์ž…์ด ์—†๋Š” ๊ฒฝ๊ณ„์— ๋ถ™์ด๋Š” ๊ณ„์•ฝ์„œ๋‹ค."

๋‚ด์ผ์€ ์›น๋ทฐ ๋ธŒ๋ฆฟ์ง€ ํ˜ธ์ถœ๋ถ€์—์„œ (window as any)๋ฅผ ๊ฒ€์ƒ‰ํ•ด global.d.ts๋กœ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ๊ฒ ๋‹ค. ์„ค์ •์„ ๊ณ ์น  ๋•Œ๋Š” ์™œ ์ด ์˜ต์…˜์ด ํ•„์š”ํ•œ์ง€๋„ PR ์„ค๋ช…์— ๋‚จ๊ฒจ์•ผ ํŒ€์ด ๊ฐ™์€ ๊ธฐ์ค€์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.