> ## Documentation Index
> Fetch the complete documentation index at: https://sonamu.cartanova.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# tsconfig.json

> TypeScript 설정하기

Sonamu 프로젝트는 TypeScript로 작성되며, API와 Web 각각 독립적인 `tsconfig.json`을 가지고 있습니다. 각 환경에 최적화된 설정을 사용합니다.

## 프로젝트 구조

<FileTree>
  * my-project/ - api/ - tsconfig.json # API 서버용 설정 - tsconfig.schemas.json # 스키마 생성용 -
    tsconfig.types.json # 타입 생성용 - web/ - tsconfig.json # React 앱용 설정 - tsconfig.node.json #
    Vite 설정용
</FileTree>

<Info>API와 Web은 각각 독립적인 TypeScript 프로젝트입니다. 설정이 서로 분리되어 있습니다.</Info>

## API 서버 설정

### 기본 tsconfig.json

```json title="api/tsconfig.json" theme={null}
{
  "compilerOptions": {
    /* Basic Options */
    "target": "esnext",
    "module": "esnext",
    "outDir": "dist",
    "sourceMap": true,
    "lib": ["esnext", "dom"],

    /* Strict Type-Checking Options */
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true,
    "noImplicitThis": true,
    "alwaysStrict": true,

    /* Additional Checks */
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "useUnknownInCatchVariables": true,

    /* Module Resolution Options */
    "moduleResolution": "bundler",
    "esModuleInterop": true,

    /* Experimental Options */
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,

    /* Advanced Options */
    "forceConsistentCasingInFileNames": true,
    "noErrorTruncation": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "noUncheckedIndexedAccess": true
  },
  "include": ["src/**/*.ts", "src/**/*.json"],
  "exclude": [
    "node_modules",
    "dist/*",
    "public",
    // "src/**/*.test.ts",  // 테스트 파일도 타입 체크하므로 주석 처리
    "**/__mocks__/**",
    "vite.config.ts"
  ]
}
```

### 주요 옵션 설명

<Tabs>
  <Tab title="모듈 설정" icon="cube">
    ```json theme={null}
    {
      "target": "esnext",           // 최신 ECMAScript 문법 사용
      "module": "esnext",            // ES 모듈 출력
      "moduleResolution": "bundler"  // Vite/esbuild와 호환
    }
    ```

    **moduleResolution: "bundler"**

    * Node.js의 `node` 모드 대신 번들러 모드 사용
    * Vite와 esbuild가 모듈을 해석하는 방식과 일치
    * `package.json`의 `exports` 필드 지원

    <Warning>
      `moduleResolution: "node"`를 사용하면 Vite와 충돌할 수 있습니다.
    </Warning>
  </Tab>

  <Tab title="데코레이터" icon="sparkles">
    ```json theme={null}
    {
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true
    }
    ```

    **Sonamu API에서 필수**

    * API 메서드에 `@api` 데코레이터 사용
    * 트랜잭션에 `@transactional` 데코레이터 사용
    * 파일 업로드에 `@upload` 데코레이터 사용

    **사용 예시:**

    ```typescript theme={null}
    import { BaseModelClass, api, transactional } from "sonamu";

    class UserModelClass extends BaseModelClass<
      UserSubsetKey,
      UserSubsetMapping,
      UserSubsetQueries
    > {
      @api({ httpMethod: "GET" })
      async findById(subset: UserSubsetKey, id: number) {
        const rdb = this.getPuri("r");
        return rdb.table("users").where("id", id).first();
      }

      @api({ httpMethod: "POST" })
      @transactional()
      async save(data: UserSaveParams) {
        const wdb = this.getDB("w");
        return this.upsert(wdb, data);
      }
    }

    export const UserModel = new UserModelClass();
    ```

    <Info>
      Entity는 `entity.json` 파일로 정의하며, TypeScript 데코레이터는 사용하지 않습니다. 자세한 내용은 [Entity 정의하기](/ko/core-concepts/entity/defining-entities)를 참고하세요.
    </Info>
  </Tab>

  <Tab title="Strict 모드" icon="shield-check">
    ```json theme={null}
    {
      "strict": true,
      "noImplicitAny": true,
      "strictNullChecks": true,
      "strictFunctionTypes": true,
      "strictBindCallApply": true,
      "strictPropertyInitialization": true,
      "noImplicitThis": true,
      "alwaysStrict": true
    }
    ```

    Sonamu는 **모든 strict 옵션을 활성화**합니다.

    * 타입 안정성 극대화
    * 런타임 에러 사전 방지
    * 코드 품질 향상

    자세한 내용은 [타입 체크](/ko/configuration/typescript/type-checking)를 참고하세요.
  </Tab>

  <Tab title="추가 체크" icon="list-check">
    ```json theme={null}
    {
      "noUnusedLocals": true,
      "noUnusedParameters": true,
      "noImplicitReturns": true,
      "noFallthroughCasesInSwitch": true,
      "useUnknownInCatchVariables": true,
      "noUncheckedIndexedAccess": true
    }
    ```

    **코드 품질 향상 옵션:**

    * `noUnusedLocals`: 사용하지 않는 변수 경고
    * `noUnusedParameters`: 사용하지 않는 파라미터 경고
    * `noImplicitReturns`: 모든 경로에서 return 필요
    * `noUncheckedIndexedAccess`: 배열/객체 접근 시 undefined 체크
  </Tab>
</Tabs>

### 확장 설정 파일들

Sonamu API는 코드 생성을 위해 추가 tsconfig 파일을 사용합니다.

<Accordion title="tsconfig.schemas.json - 스키마 생성용" icon="database">
  ```json title="api/tsconfig.schemas.json" theme={null}
  {
    "extends": "./tsconfig.json",
    "include": ["src/sonamu.generated.ts"],
    "exclude": ["src/**/*.types.ts"]
  }
  ```

  **용도:**

  * `sonamu.generated.ts` 파일 생성
  * Entity 스키마 타입 생성
  * DB 스키마 → TypeScript 타입 변환

  **사용 시점:**

  ```bash theme={null}
  # Sonamu가 자동으로 사용
  pnpm sonamu entity:load
  ```
</Accordion>

<Accordion title="tsconfig.types.json - 타입 생성용" icon="code">
  ```json title="api/tsconfig.types.json" theme={null}
  {
    "extends": "./tsconfig.json",
    "include": ["src/**/*.types.ts"],
    "references": [{ "path": "./tsconfig.schemas.json" }]
  }
  ```

  **용도:**

  * API 응답 타입 생성
  * Request/Response 타입 정의
  * 프론트엔드와 타입 공유

  **사용 시점:**

  ```bash theme={null}
  # Web으로 타입 동기화
  pnpm sonamu sync:types
  ```
</Accordion>

## Web (React) 설정

```json title="web/tsconfig.json" theme={null}
{
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src", "src/routeTree.gen.ts"],
  "references": [{ "path": "./tsconfig.node.json" }]
}
```

### API와의 차이점

| 옵션                 | API       | Web         | 이유                      |
| ------------------ | --------- | ----------- | ----------------------- |
| `moduleResolution` | `bundler` | `Bundler`   | Vite가 번들러 방식 사용         |
| `jsx`              | -         | `react-jsx` | React 17+ JSX Transform |
| `noEmit`           | `false`   | `true`      | Vite가 빌드 담당             |
| `isolatedModules`  | -         | `true`      | Vite의 esbuild 요구사항      |
| `paths`            | -         | `@/*`       | 절대 경로 import            |

<Info>
  API는 `moduleResolution: "bundler"` (소문자), Web은 `moduleResolution: "Bundler"` (대문자)를
  사용합니다. 둘 다 Vite가 번들러 방식으로 모듈을 해석합니다.
</Info>

### Path Mapping

```json theme={null}
{
  "paths": {
    "@/*": ["./src/*"]
  }
}
```

절대 경로로 import할 수 있습니다:

```typescript theme={null}
// ❌ 상대 경로
import { Button } from "../../../components/Button";

// ✅ 절대 경로
import { Button } from "@/components/Button";
```

자세한 내용은 [Path Mapping](/ko/configuration/typescript/path-mappings)을 참고하세요.

## 타입 체크 실행

<Tabs>
  <Tab title="API" icon="server">
    ```bash theme={null}
    cd api

    # 타입 체크만
    pnpm tsc --noEmit

    # Watch 모드
    pnpm tsc --noEmit --watch
    ```
  </Tab>

  <Tab title="Web" icon="browser">
    ```bash theme={null}
    cd web

    # 타입 체크만
    pnpm tsc --noEmit

    # Watch 모드
    pnpm tsc --noEmit --watch
    ```
  </Tab>

  <Tab title="전체" icon="folder">
    ```bash theme={null}
    # 프로젝트 루트에서
    pnpm -r tsc --noEmit

    # API와 Web을 동시에 체크
    ```
  </Tab>
</Tabs>

<Tip>개발 중에는 `--watch` 모드로 실시간 타입 체크를 권장합니다.</Tip>

## 일반적인 문제 해결

<Accordion title="모듈을 찾을 수 없음" icon="magnifying-glass">
  **증상:**

  ```
  Cannot find module 'sonamu' or its corresponding type declarations.
  ```

  **원인:**

  * `node_modules`가 설치되지 않음
  * 잘못된 import 경로

  **해결:**

  ```bash theme={null}
  # 의존성 재설치
  pnpm install

  # 타입 정의 확인
  ls node_modules/sonamu/dist/*.d.ts
  ```
</Accordion>

<Accordion title="데코레이터 에러" icon="sparkles">
  **증상:**

  ```
  Experimental support for decorators is a feature that is subject to change
  ```

  **원인:**

  * `experimentalDecorators`가 비활성화됨

  **해결:**

  ```json theme={null}
  {
    "compilerOptions": {
      "experimentalDecorators": true,
      "emitDecoratorMetadata": true
    }
  }
  ```
</Accordion>

<Accordion title="JSX 에러 (Web)" icon="react">
  **증상:**

  ```
  Cannot use JSX unless the '--jsx' flag is provided.
  ```

  **원인:**

  * `jsx` 옵션이 설정되지 않음

  **해결:**

  ```json theme={null}
  {
    "compilerOptions": {
      "jsx": "react-jsx"
    }
  }
  ```

  **React 17+ 필수 설정**
</Accordion>

<Accordion title="Path Mapping 작동 안 함" icon="route">
  **증상:**

  ```
  Cannot find module '@/components/Button'
  ```

  **원인:**

  * `paths` 설정 누락
  * `baseUrl` 설정 필요

  **해결:**

  ```json theme={null}
  {
    "compilerOptions": {
      "baseUrl": ".",
      "paths": {
        "@/*": ["./src/*"]
      }
    }
  }
  ```

  **Vite 설정도 필요:**

  ```typescript title="vite.config.ts" theme={null}
  import path from "path";

  export default {
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./src"),
      },
    },
  };
  ```
</Accordion>

## 커스터마이징

### 추가 라이브러리 타입

```json theme={null}
{
  "compilerOptions": {
    "lib": ["esnext", "dom", "dom.iterable", "webworker"]
  }
}
```

### 더 엄격한 체크

```json theme={null}
{
  "compilerOptions": {
    "noPropertyAccessFromIndexSignature": true,
    "exactOptionalPropertyTypes": true,
    "noUncheckedIndexedAccess": true
  }
}
```

<Warning>이 옵션들은 기존 코드와 호환성 문제를 일으킬 수 있습니다.</Warning>

### include/exclude 패턴

```json theme={null}
{
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.json"],
  "exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts", "**/__mocks__/**"]
}
```

## 다음 단계

<CardGroup cols={2}>
  <Card title="타입 체크" icon="shield-check" href="/ko/configuration/typescript/type-checking">
    Strict 모드와 타입 체크 옵션을 학습하세요
  </Card>

  <Card title="Path Mapping" icon="route" href="/ko/configuration/typescript/path-mappings">
    절대 경로 import를 설정하세요
  </Card>

  <Card title="Entity 정의" icon="database" href="/ko/core-concepts/entity/defining-entities">
    Entity를 정의하세요
  </Card>

  <Card title="API 타입" icon="code" href="/ko/core-concepts/type-system/entity-types">
    API 요청/응답 타입을 정의하세요
  </Card>
</CardGroup>
