TypeScript 簡明教程:基本類型(一)

本文爲系列文章《TypeScript 簡明教程》中的一篇。javascript

  1. 認識 TypeScript
  2. 安裝 TypeScript
  3. 基本類型(一)

從這篇文章,咱們開始講解 TypeScript 的類型系統。以前咱們說到,TypeScript 是 JavaScript 的超集,是 JavaScript 的繼承與發展,即所謂的『加強版』。這一點,從 TypeScript 中的基本類型能夠看出。TS 的數據類型與 JS 幾乎相同,此外還額外提供一些數據類型方便咱們使用。前端

首先,咱們來看 JavaScript 中 6 種原始數據類型在 TypeScript 中的使用,它們分別爲:numberstringbooleannullundefinedsymboljava

原始數據類型

number 類型

TypeScript 中,使用 number 表示變量爲數值類型。與 JavaScript 一致,TypeScript 中全部數值都是浮點數,支持二進制、八進制、十進制和十六進制四種表示方法。es6

let decimalNumber: number = 42
let hexNumber: number = 0x2A
let binaryNumber: number = 0b101010
let octalNumber: number = 0o52
複製代碼

二進制和八進制表示採用 ES6 新的寫法,分別使用前綴 `0b`(或 `0B`)和 `0o`(或 `0O` 英文字母 O)表示。從 ES5 開始,再也不容許使用前綴 `0` 表示八進制。若是 `tsconfig` 中 target 高於 ES5 版本,TypeScript 將會出現提示:禁止使用前綴 `0` 表示八進制。 編程

除了浮點數之外,JavaScript 中還有一組特別的數值:Infinity-InfinityNaN,它們也屬於 number 類型。編程語言

const positiveLargestNumber: number = Infinity
const negativeLargestNumber: number = -Infinity

const notANumber: number = NaN
複製代碼

Infinity 即正無窮,用以表示超出 JS 所能表示的最大值的數值,不一樣環境下這個值有所不一樣,可經過 Number.MAX_VALUE 查看,通常爲 1.7976931348623157E+308。與之相對應的是 -Infinity,表示負無窮。函數

注意區分**負無窮**和**無窮小**兩個概念。負無窮表示比任何數都小的一個負數值,無窮小表示以 0 爲極限,無限趨於零的一個正數值。JS 中的無窮小值可經過 `Number.MIN_VALUE` 查看,通常爲 `5E-324`。 post

NaN 表示一個本應返回數值的操做數未返回數值的狀況。好比:學習

let newNumber: number = Number('a') // => NaN
複製代碼

更多內容能夠參考:ECMAScript 6 入門 - 數值的擴展ui

string 類型

和其餘編程語言同樣,字符串是必不可少的一種類型,用於表示文本數據。能夠經過 string 聲明某個變量爲字符串類型。

const theAnswer: number = 42
let sentence: string = `The Answer to the Ultimate Question of Life, The Universe, and Everything is ${ theAnswer }.`
複製代碼

TypeScript 中你依舊可使用雙引號(")和單引號(')來表示字符串。除此之外,你還可使用 ES6 提供的 模板字符串 語法。TypeScript 會自動將其編譯爲字符串拼接的形式。

// 編譯結果
var theAnswer = 42;
var sentence = "The Answer to the Ultimate Question of Life, The Universe, and Everything is " + theAnswer + ".";
複製代碼

boolean 類型

布爾值能夠說是最基本的數據類型了,它的可能取值只有兩個:truefalse。TypeScript 中使用 boolean 表示布爾值類型。

let num: number = -10
let isPositive: boolean = num > 0
複製代碼

symbol 類型

symbol 是 ES6 新增的數據類型,用於表示獨一無二的值,只能 Symbol 函數生成。更多內容能夠參考:ECMAScript 6 入門 - Symbol

const sym: symbol = Symbol()
複製代碼

事實上,TypeScript 官網上並無詳細介紹 symbol 這一基礎數據類型。想來緣由有二:

  1. symbol 值只能經過 Symbol() 函數生成,因爲類型推斷(後面會講)的存在,無需特別聲明變量爲 symbol 類型。
  2. symbol 的惟一性依賴於底層實現,不太好作 polyfill,因此對於編譯 target 低於 ES6 版本的狀況,並不推薦使用 symbol

不過,出於完整性的考慮,這裏仍是簡要提一下。

undefinednull 類型

JavaScript 中,undefinednull 都被用來表示空值。做爲兩個原始數據類型,undefined 類型的變量只能被賦值爲 undefinednull 類型的變量只能被賦值爲 null

// 通常來講,直接定義一個 undefined 或者 null 類型的變量並無太大意義
let u: undefined = undefined
let n: null = null
複製代碼

默認狀況下,undefinednull 是全部其餘類型的子類型。也就是說,若是 undefinednull 賦值給任何其餘類型的變量。

例如:

let person: string = 'Jerry'
person = null // 有效的
複製代碼

然而,若是在 tsconfig 中開啓了 strictNullChecks,那麼 undefinednull 就只能賦值給 voidany 類型變量以及它們自身類型的變量。強烈建議開啓這一選項,它能幫助避免不少常見的問題

undefinednull 的關係

儘管 undefinednull 都表示空值,可是它們本質上是不一樣的。undefined 表示變量已聲明但未初始化null 則在邏輯上表示一個空對象指針(這也正是 typeof null === 'object' 的緣由)。

不管什麼狀況下,都沒有必要把一個變量的值顯式地設置爲 undefined,但是一樣的規則對 null 卻不適用。換句話說,只要意在保存對象的變量尚未真正保存對象,就應該明確地讓該變量保存 null 值。 —— Nicholas C.Zakas 《JavaScript 高級程序設計》

高級類型

void 類型

void 類型表示沒有任何類型,這句話聽起來可能有些自相矛盾。不過,讓咱們來考慮這樣一種狀況:若是一個函數沒有返回值,咱們如何表示其類型?這時候 void 類型就派上用場了。這裏和 C 語言很像。

function warning(): void {
    console.log('WARNING!')
}
複製代碼

固然,這裏你也能夠指定返回值類型爲 undefined。由於 JS 中,若是函數沒有返回值,則會默認返回 undefind。不過,使用 void 類型可使表意更清晰。

然而,聲明一個 void 類型的變量並無太大的用處,由於你只能將其賦值爲 nullundefined

請注意與 void 運算符區分void 運算符的做用是:對給定的表達式進行求值,而後返回 undefined。若是你從事前端多年,你或許會比較熟悉 javascript:void(0); 這樣的代碼。感興趣的能夠看 這裏

any 類型

某種程度上,any 類型就像是 void 類型的反面,任何類型都是 any 類型的子類型。換句話說,any 類型的變量能夠被賦予任何類型的值。

let anything: any = "Ohh, that's crazy"
anything = 42
複製代碼

對於 any 類型,有兩個須要注意的點。

首先,若是變量在聲明時,沒有聲明其類型,也沒有初始化(由於類型推斷會自動判斷類型),那麼它會被當作 any 類型。

let something   // 等價於 let something: any;
something = 'autochess'
something = 6
複製代碼

其次,在 any 類型變量上能夠訪問任何屬性,即便它並不存在。

let something: any = 42
something.mayExist()    // 沒問題,由於其可能在運行時存在
something.toFixed() // 沒問題,雖然確實存在,可是編譯器並不會去檢查
複製代碼

事實上,any 類型是 TypeScript 提供的一個『跳出』方案。對於 any 類型變量,編譯器不會作任何類型檢查,直接讓它們經過類型檢查。這在引入第三方庫以及將原有 JS 代碼改寫爲 TS 時尤爲有用。

不過,注意不要濫用 any 類型。錯誤地濫用 any 類型會讓 TS 失去其存在的意義。

never 類型

never 用於表示永遠不會存在的值的類型。never 是任何類型的子類型,但沒有類型是 never 的子類型。

對於 never 類型,新手理解起來可能比較困難。可是對於 TypeScript 這樣一個分析代碼流的語言來講,never 類型是理所固然且必要的。

never 類型經常使用於兩種狀況:

  1. 用於描述從不會有返回值的函數
  2. 用於描述老是拋出錯誤的函數
// 第一種狀況
function neverStop(): never {
    while (true) {
        // do something
    }
}

// 第二種狀況
function error(message: string): never {
    throw new Error(message)
}
複製代碼

對於上述兩種狀況,函數的返回類型都是 never

never 類型也能夠用作變量的類型註解(例如:let foo: never;),可是這樣作並無什麼意義。

下面咱們經過一個例子來學習 never 類型的用法:

function checkNumber(x: string | number): boolean {
    if (typeof x === 'number') {
        return true
    } else if (typeof x === 'string') {
        return false
    }
    
    return fail('Failure')
}

function fail(message: string): never {
    throw new Error(message)
}
複製代碼

對於上面的 checkNumber 函數,若是沒有 return fail('Failure') 這一句的話,TypeScript 會報錯,由於不是全部條件語句都有返回值,當參數 x 既不是 number 也不是 string 時,函數會默認返回 undefined,然而在嚴格模式下,undefined 類型與 boolean 類型並不兼容。可是因爲 fail 函數返回的 never 類型是 boolean 的子類型,全部上述寫法能夠經過編譯。這也是 never 必須是任何類型的子類型的緣由。

關於 never 類型,這裏只是舉個例子幫助你們理解。想要真正理解 never 類型,還得結合實戰仔細揣摩才行。

總結

本篇文章主要介紹了 TypeScript 中的原始數據類型和幾個高級類型。經過這篇文章,相信你們已經能夠看出 TypeScript 類型系統的強大和完備。

固然這還不是所有,下篇文章咱們將介紹 TypeScript 中其餘幾個高級類型:ObjectArrayTupleEnum。敬請期待~

相關文章
相關標籤/搜索