TypeScript中import type與import的區別詳析

背景

這周遇到瞭一個比較奇怪的問題:如何在 TypeScript 中根據某個 enum 的取值來執行後續邏輯?

按理來說應該很簡單,這是 enum 的定義:

export enum MyEnum {
  DEFAULT = 0,
  SOME_VALUE = 1,
  SOME_OTHER_VALUE = 2,
}

然後在另一個項目中,通過 import type 來引入:

import type { MyEnum } from 'somepackage';

const someFunction = (myEnum: MyEnum) => {
  if (myEnum === MyEnum.SOME_VALUE) {
  	// some logic here
    return
  }
  if (myEnum === MyEnum.SOME_OTHER_VALUE) {
    // some logic here
    return
  }
  // some logic here
  return
}

但是這個時候 VS Code 居然提示瞭一個錯誤:

'MyEnum' cannot be used as a value because it was imported using 'import type'.ts(1361)

我的第一反應是,難道在 TypeScript 裡不能檢查 enum 的取值?這也太說不過去瞭吧…

後來折騰瞭半天,發現按照提示,把 import type 換成 import 就好瞭。

import type vs import

之前沒有深入學習過 TypeScript,就是看項目裡別人怎麼用,就照貓畫虎地寫。

這次也是一樣,別人都是 import type,我就直接在其中加瞭一個我想引入的 MyEnum,結果就不行瞭,還得把 MyEnum 分開來用 import。

但這是為什麼呢?後來搜瞭一下,終於弄明白瞭。TypeScript 3.8 文檔上說:

import type only imports declarations to be used for type annotations and declarations. It always gets fully erased, so there’s no remnant of it at runtime.

大概意思就是:import type 是用來協助進行類型檢查和聲明的,在運行時是完全不存在的。

這下終於明白上面 enum 的那個問題瞭:如果通過 import type 來引入 MyEnum,固然可以在構建時起到類型檢查的作用,但在運行時 MyEnum 就不存在瞭,當然就無法檢查 MyEnum.SOME_VALUE 之類的取值瞭!

可是仔細一想,TypeScript 本來就不應該在運行時存在呀!為什麼還要用 import type 呢?

其實,在少部分情況下(剛好就包括 enum ),import 的內容在運行時的確是存在的,使用 import type 和import 就會有區別。

使用 import type 的好處

import type 是 TypeScript 3.8 才加入的,為什麼要加入這個功能呢?使用 import type 而不是 import 有什麼好處?

簡單來說,大部分情況下用 import 完全就可以瞭,但在比較罕見的情況下,會遇到一些問題,這時候使用 import type 就可以解決問題瞭。

當然,我也沒碰到過這樣的問題,隻不過項目裡在所有引入 TypeScript 類型的地方用的基本都是 import type,也就跟著用瞭。這樣當然是更保險一些,沒啥壞處。

參考鏈接

Do I need to use the “import type” feature of TypeScript 3.8 if all of my imports are from my own file?

Runtime typesafety in typescript

總結

到此這篇關於TypeScript中import type與import區別的文章就介紹到這瞭,更多相關TS import type與import區別內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: