# 編譯選項

### 進入正題

筆者在前一篇文章向大家介紹了如何在 Deno 中使用多模組開發、 `Url import` 、 `DenoLand` 的介紹。

本篇就來談談 Deno 對 TypeScript 支援的其他項目吧！

#### 母湯檢查喔！

我們都知道， TypeScript 程式碼執行時會先經過型別檢查。然而，檢查的行為其實是非常消耗效能的。假設我們已經對程式碼進行過測試，就不需要在每次執行時都進行型別檢查。這時，我們可以使用 `--no-check` 標籤：

```
deno run --no-check main.ts
```

該標籤適用於以下指令：

```
deno run
deno test
deno cache
deno bundle
```

> 需要注意的是：
>
> 在使用 `--no-check` 以後， TypeScript 不會進行型別檢查。也因為這樣，我們不能自動刪除僅導入 `import` 和 `export` 的 `type` 。
>
> 對此， 貼心的 TypeScript 也提供了 [import type 和 export type 語法](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-8.html#type-only-imports-and-exports)。(要使用此語法，需要確保 Deno 的版本在 `1.4.0` 以上並使用 `--unstable` 標籤以及對 TypeScript 編譯器進行以下設定：
>
> * importsNotUsedAsValues: error
> * isolatedModules: true
>
> )

#### 使用外部類型定義

TypeScript 天生就擁有健全型別系統。若我們在開發相關應用時需要用到原生 JavaScript 編寫的第三方模組，該如何讓它也支援類型推論呢。為了解決這個問題， Deno 提供三種引用類型定義文件的方法：

**Compiler hint**

如果我們要導入 JavaScript 模組，並且知道該模組在哪進行類型定義，我們就可以在導入時指定類型定義。此方法會告知 Deno `.d.ts` 文件的位置以及與它們相關的 JavaScript 模組程式碼。使用方法如下：

例設： 我們有一個第三方模組 `foo.js` 。並且，我們知道它的類型定義文件 `foo.d.ts` ，我們可以這麼做：

```typescript
// @deno-types="./foo.d.ts"
import * as foo from "./foo.js";
```

> 什麼是類型定義文件？
>
> 可以參考[連結](https://tasaid.com/blog/20171102225101.html)

**Triple-slash reference directive in JavaScript files**

假設使用者要提供可在 Deno 中使用的第三方模組，並且為 Deno 標記好類型定義，可以在程式碼中使用三斜杠指令，就像是：

```
/// <reference types="./foo.d.ts" />
export const foo = "foo";
```

**X-TypeScript-Types custom header**

除了使用三斜杠指令以外，我們也可以使用自定義 HTTP 標題的 `X-TypeScript-Types` 達到同樣的目的。

自定義標題的運作方式與三斜杠引用方法相同，表示 JavaScript 模組本身的內容不需要修改，類型定義的位置可以由服務器本身確定。

> 注意：並不是所有類型定義都支持該功能！ Deno 使用 `compiler hint` 載入指定的 `.d.ts` 檔案，但是有些 `.d.ts` 檔案包含了 Deno 不支援的功能。具體來說，某些 `.d.ts` 檔案希望使用模組解析的邏輯從其他模組中載入、引用類型定義。 筆者必須老實說：因為研究所推甄的原因，我還沒有嘗試這項功能，之後有空我會找時間去跳坑再把心得補上。

#### 客製化 TypeScript Compiler Options

在 Deno 的生態系中，任何有關嚴格模式的 TypeScript 編譯選項都是開啟的。如果讀者希望可以對 TypeScript Compiler Options 做到更寬鬆的訂製，我們可以用 `tsconfig.json` 做到：

```javascript
{
  "compilerOptions": {
    "allowJs": false,
    "allowUmdGlobalAccess": false,
    "allowUnreachableCode": false,
    "allowUnusedLabels": false,
    "alwaysStrict": true,
    "assumeChangesOnlyAffectDirectDependencies": false,
    "checkJs": false,
    "disableSizeLimit": false,
    "generateCpuProfile": "profile.cpuprofile",
    "jsx": "react",
    "jsxFactory": "React.createElement",
    "jsxFragmentFactory": "React.Fragment",
    "lib": [],
    "noFallthroughCasesInSwitch": false,
    "noImplicitAny": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitUseStrict": false,
    "noStrictGenericChecks": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveConstEnums": false,
    "removeComments": false,
    "resolveJsonModule": true,
    "strict": true,
    "strictBindCallApply": true,
    "strictFunctionTypes": true,
    "strictNullChecks": true,
    "strictPropertyInitialization": true,
    "suppressExcessPropertyErrors": false,
    "suppressImplicitAnyIndexErrors": false,
    "useDefineForClassFields": false
  }
}
```

上面是目前 Deno 支援的編譯選項，在編輯好你的 `tsconfig.json` 後，在執行程式碼時需加入 `-c tsconfig.json` ：

```
deno run -c tsconfig.json mod.ts
```

> 換句話說：其他 [TypeScript Docs](https://www.typescriptlang.org/docs/handbook/compiler-options.html) 所提到的編譯選項，移到 Deno 上執行時有兩種可能：
>
> 1. Deno 真的不支援
> 2. TypeScript 告訴你這是實驗性功能

### 延伸閱讀

> 同樣的事情在不同人眼中可能會有不同的見解、看法。
>
> 在讀完本篇以後，筆者也強烈建議大家去看看以下文章，或許會對型別、變數宣告...等觀念有更深層的看法唷！

* [Deno Manual](https://deno.land/manual@v1.4.4/getting_started/typescript)
* [TypeScript Docs](https://www.typescriptlang.org/docs/handbook/compiler-options.html)
* [Said:听说 - 類型定義文件](https://tasaid.com/blog/20171102225101.html)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ianchen0119.gitbook.io/deno/deno-cli/bian-yi-xuan-xiang.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
