TypeScript 是 JAVAScript 的超集,一方面給動態類型的 js 增加了類型校驗,另一方面擴展了 js 的各種功能。
原始數據類型
- 字符串
- 數值
- 布爾
- null
- undefined
- Symbol
- BigInt
let str: string = '周小黑'
let age: number = 18
let beautiful: boolean = true
let n: null = null
let u: undefiend = undefined
let s: Symbol = Symbol('1')
let int: BigInt = BigInt(10)
any、unknown、void、never
- any:任意類型,是一切類型的父類型,也是一切類型的子類型。會跳過類型檢查,和我們平時寫js一樣
- unknown:未知類型,是一切類型的父類型,但不是一切類型的子類型。比 any 更安全,比如聲明了一個對象為 unkonw 要讀取屬性或調用方法時需要先進行具體類型判斷或用 as 進行類型斷言,收窄類型后才能讀取
- void:沒有任何返回值的函數,聲明一個 void 類型的變量沒有什么用,因為只能賦值為 undefined 和 null(只在 --strictNullChecks 未指定時)
- never:不存在值的類型
any、unknonwn是所有類型的父類型,null、undefined、never是所有類型的子類型
Object、object、{}
- Object:原始對象類型,支持所有類型,注意為非原始數據類型時不能訪問值的任何屬性
- object:普通對象類型,只能是非原始數據類型對象、數組、函數這些,我們不能訪問值的任何屬性
- {}:對象字面量,無自身屬性的對象類型,不能進行屬性操作
let num: Object = 12
let girl: Object = { age: 18 }
console.log(girl.age) // 會報錯
let arr: object = [1, 2, 3]
console.log(arr[0]) // 會報錯
console.log(arr) // 可以正常運行
let person: {} = {name: 'zhou'}
console.log(boy.name) // 會報錯
// 可以正常運行
let boy: {name: string} = {name: 'zhou'}
boy.name = '周'
console.log(boy)
注意需要訪問某個對象的屬性或方法時,應該定義具體的屬性類型或通過 interface 接口定義類型,才能進行屬性的讀取、賦值操作。
其他常用類型、DOM類型
- 其他類型:除了上面提到的一些類型,還有 Function、Date、RegExp、Error、Promise
- Array和Tuple類型:Tuple元組類型和數組類型類似,不過元組表示一個已知元素數量和元素類型的數組(各元素的類型不必相同)
- Enum類型:枚舉類型
- DOM類型:Document、htmlElement、NodeList、Event、MouseEvent
interface、type
- interface:接口,只能定義對象結構的數據類型,可以通過extends擴展,重復定義會被合并
- type:類型別名,可以定義原始類型,可以通過&符號合并類型,不可以重復定義;除了類型還可以用來限制值;注意類型后面需要用 = 來寫,而 interface 則不用
兩個都可以用來定義類型,也比較類似,推薦優先使用 interface。
聯合類型、交叉類型
- 聯合類型:用 | 表示聯合類型,相當于或
- 交叉類型:用 & 合并多個類型,相當于把多個類型合并到一起,可以用于合并多個 interface 或 type
type Person = {
name: string
age: number | string
}
interface Man {
money: number
}
let boy: Person & Man = {
name: 'zhou',
age: '18',
money: 100
}
console.log(boy)
符號
- & 且
- | 或
- ! 非
- ?? 空值合并運算符
- ?. 可選鏈操作符,用在獲取對象的深層屬性或方法前
- ? 加在類型上表示可選參數或者可選屬性,一般用在對象屬性或者函數參數上
interface Person {
name: string,
age?: number
}
let man: Person = {
name: 'zhou'
}
function add(x: number, y?: number): number {
return y ? (x + y) : x
}
add(10)
add(10, 12)
字面量
這個用來將變量的值限制成預定的,是對值得限定,看著有點像聯合類型(是對類型得限定)
let a: 10 | 'zhou' | [1, 2, 4]
// 也可以用 type 類型別名來寫成下面得形式
// type A = 10 | 'zhou' | [1, 2, 4]
// let a: A
a = [1, 2, 4]
a = false // Type 'false' is not assignable to type '"zhou" | 10 | [1, 2, 4]'.ts(2322)
class 類
- ts 支持面向對象的所有特性,比如:類、接口等
- 類可以通過 implements 去實現接口 interface
- 修飾符:public / private / protected / abstract / static(js中也有)
泛型
泛型相當于一個占位符,可以理解成函數參數,使用的時候傳進來的是什么,在內部就可以用用占位符去使用,一般多用于函數中,使用時用一對尖括號加上占位符,多用字母 T 占位。就是把定義的類型變量想象成一個函數,只不過參數部分用尖括號傳遞,使用的時候再用尖括號把具體的類型傳進去
// 函數
function func<T>(arg: T): T {
return arg
}
// interface 接口
interface Person<T> {
name: string,
age: number,
custom: T
}
let man: Person<boolean> = {
name: 'zhou',
age: 18,
custom: true
}
// 元組
type Ftype<T, U> = [number, T, boolean, U]
let fruits: Ftype<Function, string> = [1, () => {}, false, '水果']
內置泛型工具
- Partial
- Required
- Readonly
- Pick
- Exclude
- Extract
- Omit
- Record
- ReturnType
- ...
關鍵字
extends
- js 中 class 類實現繼承
- ts 的 interface 接口實現繼承
- 判斷類型包含
as
類型斷言,將一個大范圍的類型收窄
in
遍歷,從多個類型中去遍歷出每個類型
keyof
ts 2.1 版本中引入,用于獲取某種類型中的所有鍵,返回的是聯合類型(跟我們用 Object.keys 獲取對象的所有屬性鍵類似,只不過 Object.keys 返回的是所有鍵名數組)。
獲取到類型的鍵后,我們就可以訪問到鍵對應的類型:
interface Person {
name: string,
age: number
}
type Name = Person['name']
type P1 = Person['name' | 'age'] // string | number
// 上面的 P1 也就相當于:
type P2 = Person[keyof Person] // string | number
typeof
- js 中判斷類型
- ts 中獲取一個變量的申明類型
infer
推斷的占位,當某個類型不確定時,就可以暫時表示為 xx
interface、type、對象屬性多個中的符號
- interface 和 type 中多個可以用分號、逗號,也可以不加,也可以混用,不過團隊開發中盡量統一成一種寫法
- 對象屬性多個只能用逗號
interface Person {
name: string
age: number;
gender: string,
}
let man: Person = {
name: 'zhou',
age: 18,
gender: '男'
}