TypeScript 支持與 JavaScript 幾乎相同的數(shù)據(jù)類型,此外還提供了實用的枚舉類型方便我們使用。
布爾值
最基本的數(shù)據(jù)類型就是簡單的 true/false 值,在JavaScript 和 TypeScript 里叫做 boolean(其它語言中也一樣)。
let isDone: boolean = false;
isDone = true;
// isDone = 2 // error
數(shù)字
和 JavaScript 一樣,TypeScript 里的所有數(shù)字都是浮點數(shù)。 這些浮點數(shù)的類型是 number。 除了支持十進制和十六進制字面量,TypeScript 還支持 ECMAScript 2015中引入的二進制和八進制字面量。
let a1: number = 10 // 十進制
let a2: number = 0b1010 // 二進制
let a3: number = 0o12 // 八進制
let a4: number = 0xa // 十六進制
字符串
JavaScript 程序的另一項基本操作是處理網(wǎng)頁或服務(wù)器端的文本數(shù)據(jù)。 像其它語言里一樣,我們使用 string 表示文本數(shù)據(jù)類型。 和 JavaScript 一樣,可以使用雙引號(")或單引號(')表示字符串
let name:string = 'tom'
name = 'jack'
// name = 12 // error
let age:number = 12
const info = `My name is ${name}, I am ${age} years old!`
undefined 和 null
TypeScript 里,undefined 和 null 兩者各自有自己的類型分別叫做 undefined和 null。 它們的本身的類型用處不是很大:
let u: undefined = undefined
let n: null = null
默認情況下 null 和 undefined 是所有類型的子類型。 就是說你可以把 null 和 undefined 賦值給 number 類型的變量。
數(shù)組
TypeScript 像 JavaScript 一樣可以操作數(shù)組元素。 有兩種方式可以定義數(shù)組。 第一種,可以在元素類型后面接上[],表示由此類型元素組成的一個數(shù)組:
let list1: number[] = [1, 2, 3]
第二種方式是使用數(shù)組泛型,Array<元素類型>:
let list2: Array<number> = [1, 2, 3]
元組 Tuple
元組類型允許表示一個已知元素數(shù)量和類型的數(shù)組,各元素的類型不必相同。 比如,你可以定義一對值分別為 string 和 number 類型的元組。
let t1: [string, number]
t1 = ['hello', 10] // OK
t1 = [10, 'hello'] // Error
當(dāng)訪問一個已知索引的元素,會得到正確的類型:
console.log(t1[0].substring(1)) // OK
console.log(t1[1].substring(1)) // Error, 'number' 不存在 'substring' 方法
枚舉
enum 類型是對 JavaScript 標(biāo)準(zhǔn)數(shù)據(jù)類型的一個補充。 使用枚舉類型可以為一組數(shù)值賦予友好的名字。
enum Color {
Red,
Green,
Blue
}
// 枚舉數(shù)值默認從0開始依次遞增
// 根據(jù)特定的名稱得到對應(yīng)的枚舉數(shù)值
let myColor: Color = Color.Green // 0
console.log(myColor, Color.Red, Color.Blue)
默認情況下,從 0 開始為元素編號。 你也可以手動的指定成員的數(shù)值。 例如,我們將上面的例子改成從 1 開始編號:
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green
或者,全部都采用手動賦值:
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green
枚舉類型提供的一個便利是你可以由枚舉的值得到它的名字。 例如,我們知道數(shù)值為 2,但是不確定它映射到 Color 里的哪個名字,我們可以查找相應(yīng)的名字:
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2]
console.log(colorName) // 'Green'
any
有時候,我們會想要為那些在編程階段還不清楚類型的變量指定一個類型。 這些值可能來自于動態(tài)的內(nèi)容,比如來自用戶輸入或第三方代碼庫。 這種情況下,我們不希望類型檢查器對這些值進行檢查而是直接讓它們通過編譯階段的檢查。 那么我們可以使用 any 類型來標(biāo)記這些變量:
let notSure: any = 4
notSure = 'maybe a string'
notSure = false // 也可以是個 boolean
在對現(xiàn)有代碼進行改寫的時候,any 類型是十分有用的,它允許你在編譯時可選擇地包含或移除類型檢查。并且當(dāng)你只知道一部分數(shù)據(jù)的類型時,any 類型也是有用的。 比如,你有一個數(shù)組,它包含了不同的類型的數(shù)據(jù):
let list: any[] = [1, true, 'free']
list[1] = 100
void
某種程度上來說,void 類型像是與 any 類型相反,它表示沒有任何類型。 當(dāng)一個函數(shù)沒有返回值時,你通常會見到其返回值類型是 void:
/* 表示沒有任何類型, 一般用來說明函數(shù)的返回值不能是undefined和null之外的值 */
function fn(): void {
console.log('fn()')
// return undefined
// return null
// return 1 // error
}
聲明一個 void 類型的變量沒有什么大用,因為你只能為它賦予 undefined 和 null:
let unusable: void = undefined
object
object 表示非原始類型,也就是除 number,string,boolean之外的類型。
使用 object類型,就可以更好的表示像 Object.create 這樣的 API。例如:
function fn2(obj:object):object {
console.log('fn2()', obj)
return {}
// return undefined
// return null
}
console.log(fn2(new String('abc')))
// console.log(fn2('abc') // error
console.log(fn2(String))
聯(lián)合類型
聯(lián)合類型(Union Types)表示取值可以為多種類型中的一種
需求1: 定義一個一個函數(shù)得到一個數(shù)字或字符串值的字符串形式值
function toString2(x: number | string) : string {
return x.toString()
}
需求2: 定義一個一個函數(shù)得到一個數(shù)字或字符串值的長度
function getLength(x: number | string) {
// return x.length // error
if (x.length) { // error
return x.length
} else {
return x.toString().length
}
}
類型斷言
通過類型斷言這種方式可以告訴編譯器,“相信我,我知道自己在干什么”。 類型斷言好比其它語言里的類型轉(zhuǎn)換,但是不進行特殊的數(shù)據(jù)檢查和解構(gòu)。 它沒有運行時的影響,只是在編譯階段起作用。 TypeScript 會假設(shè)你,程序員,已經(jīng)進行了必須的檢查。
類型斷言有兩種形式。 其一是“尖括號”語法, 另一個為 as 語法
/*
類型斷言(Type Assertion): 可以用來手動指定一個值的類型
語法:
方式一: <類型>值
方式二: 值 as 類型 tsx中只能用這種方式
*/
/* 需求: 定義一個函數(shù)得到一個字符串或者數(shù)值數(shù)據(jù)的長度 */
function getLength(x: number | string) {
if ((<string>x).length) {
return (x as string).length
} else {
return x.toString().length
}
}
console.log(getLength('abcd'), getLength(1234))
類型推斷
類型推斷: TS會在沒有明確的指定類型的時候推測出一個類型
有下面2種情況: 1. 定義變量時賦值了, 推斷為對應(yīng)的類型. 2. 定義變量時沒有賦值, 推斷為any類型
/* 定義變量時賦值了, 推斷為對應(yīng)的類型 */
let b9 = 123 // number
// b9 = 'abc' // error
/* 定義變量時沒有賦值, 推斷為any類型 */
let b10 // any類型
b10 = 123