Let Express.js support TypeScipt

npm install --save-dev @type/express

----- begin package.json -----
{
  "name": "sample-express",
  "type": "module",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "express": "^4.18.2",
    "node-fetch": "^3.2.6"
  },
  "devDependencies": {
    "@types/express": "^5.0.0",
    "karma": "^6.4.4",
    "typescript": "^5.7.3"
  }
}
----- end package.json -----

----- begin tsconfig.json -----
{
  "compilerOptions": {
    "esModuleInterop": true,
    "module": "ES6",
    "moduleResolution": "node",
    "target": "ES6",
    "noImplicitAny": true
  }
}
----- end tsconfig.json -----

defining custom types
----- begin custom.d.ts ------
type newType = {
  field1: string;
  filed2: ....
  .......
};

interface newInterface {
  field1: string;
  field2: .......
  .....
};
----- end custom.d.ts ------

rename routes.js to routes.ts and modify content

rename index.js to index.ts and modify content

npx tsc // change to project root path and run the command 

目前有三個ts檔案,分別為custom.d.ts, routes.ts, index.ts 當各別下tsc custom.d.ts, tsc routes.ts, tsc index.ts, 與在資料夾的根目錄下npx tsc的結果不一樣。當各別下時,需在routes.ts的開頭加入/// ,且當下tsc index.ts時會出現錯誤:
index.ts:2:8 – error TS1259: Module ‘”/mnt/c/cmder/Project/Book/Node.js/sample-express/node_modules/@types/express/index”‘ can only be default-imported using the ‘esModuleInterop’ flag

2 import express, { Request, Response } from “express”;
~~~

node_modules/@types/express/index.d.ts:128:1
128 export = e;
~~~
This module is declared with ‘export =’, and can only be used with a default import when using the ‘esModuleInterop’ flag.

Found 1 error in index.ts:2
但如果在根目錄下npx tsc時會正確產生index.js與routes.js
請問這是為什麼?

🚀 為何 npx tsctsc index.ts 結果不同?

這是因為 全域編譯 (npx tsc) 和單獨編譯 (tsc index.ts) 的行為不同,主要原因如下:


1️⃣ npx tsc 會讀取 tsconfig.json

當你在 根目錄下執行 npx tsc,它會讀取你的 tsconfig.json 設定,因此:

  • includefiles 內的所有 .ts 檔案 都會被一起編譯。
  • tsconfig.json 內的 compilerOptions(如 esModuleInterop)會生效。

✅ 這就是為什麼 npx tsc 可以成功產生 index.jsroutes.js


2️⃣ tsc index.ts 只單獨編譯一個檔案

當你 直接執行 tsc index.ts,它的行為:

  • 不會讀取 tsconfig.json(單獨編譯時 tsconfig.json 設定不會自動生效)。
  • esModuleInterop 不會啟用,所以 import express from "express" 會報錯。