ts-checker 是一個幫助你學習 TypeScript 從入門到精通系列,不僅包括了 ts 的基礎知識,還包括了 Type-Challenges 詳細題解。
數據類型#
基本數據類型#
-
數值類型
number
const age: number = 18
-
字串類型
string
const name: string = 'lybenson'
-
布林類型
boolean
const isMale: boolean = true
-
空值
void
: 常用在函數沒有返回值時function printHeight(height: number): void { console.log(height) }
-
null
和undefined
-
any
: 任何其他類型都是any
的子類型,任何類型值都可以賦值給any
類型的變數const anyUse: any = { name: 'lybenson' } anyUse.name
-
unknown
: 未知類型,同any
類型一樣,任何類型值也可以賦值給unknown
類型的變數const unknownUse: unknown = { name: 'lybenson' } unknownUse.name // error: 'unknownUse' is of type 'unknown'.
-
never
: 表示永不存在的值的類型function error(message: string): never { throw new Error(message) }
其他數據類型#
函數類型#
定義函數類型時需要提供參數類型和返回值類型
const sum = (a: number, b: number): number => {
return a + b
}
返回值類型可不寫,ts
會自動進行類型推導
陣列類型#
陣列的類型聲明主要有下面兩種:
const arr1: number[] = []
const arr2: Array<number> = []
元組類型#
陣列一般由同種類型的值組成,但元組可以存儲不同類型的值
const student: [string, number] = ['lybenson', 18]
列舉類型#
用關鍵字 enum
聲明
enum Direction {
NORTH,
SOUTH,
EAST,
WEST
}
const direction: Direction = Direction.SOUTH
列舉值可以不寫,默認從 0 開始
聯合類型#
聯合類型表示變數的值為多種類型中的一種,強調或,用 |
符號連接
type Roles = 'CEO' | 'CTO' | 'CFO'
const userRole: Roles = 'CTO'
交叉類型#
交叉類型表示變數有類型的所有屬性,強調與,用 &
符號連接
type Student = {
name: string
}
type Employee = {
name: string
salary: number
}
// UserRole 同時具有 Student 和 Employee 屬性
type UserRole = Student & Employee
const user: UserRole = {
name: 'lybenson',
salary: 3500
}
注意
被交叉的兩個類型具有相同的屬性名,但屬性類型不同时,則屬性類型也會進行交叉,如:
type Student = {
name: number
}
type Employee = {
name: string
salary: number
}
// name 類型不同,則類型也會交叉
type UserRole = Student & Employee
// {
// name: number & string
// salary: number
// }
// 報錯: 不存在值同時具有 number 和 string 類型
const user: UserRole = {
name: 'lybenson',
salary: 3500
}
可選類型#
可選類型並不是一種具體的類型,而是一種類型泛式。
使用 ?
表示, 用來聲明變數類型或函數參數類型時指定一個類型,但不一定要求該變數或參數必須有值。本質是給原類型聯合 undefined
類型
function printName(firstName: string, lastName?: string) {
if (lastName) {
console.log(firstName + ' ' + lastName)
} else {
console.log(firstName)
}
}
// lastName 為可選類型,可不傳
printName('lybenson')
// 自定義類型中定義可選屬性
type Employee = {
name: string
salary?: number
}
const emp: Employee = {
name: 'lybenson'
}
-?
將屬性變為非可選。
只讀類型#
只讀類型同樣並不是一種具體的類型。
使用 readonly
表示屬性是只讀的,不可修改
// 定義 name 屬性是只讀的
type Employee = {
readonly name: string
salary?: number
}
const emp: Employee = {
name: 'lybenson',
salary: 3500
}
emp.name = 'jack ma' // Cannot assign to 'name' because it is a read-only property.
-readonly
將屬性變為非只讀。
自定義類型#
自定義類型常用 type
和 interface
, 兩者的區別是
type
定義聯合類型、交叉類型、元組類型、函數類型等。通常用於創建複雜的類型組合interface
常用於定義對象類型的結構。可使用繼承等特性
type
#
type User = {
name: string
age: number
sex?: number
}
type Status = 'draft' | 'published'
interface
#
interface User {
name: string
age: number
sex?: number
getName: () => string
}
注意
interface
定義的同名類型會自動合併,如:
interface User {
name: string
}
interface User {
age: number
}
// 自動合併後的類型是
interface User {
name: string
age: number
}
類型轉換#
as
#
// 強制轉換為 any
const distance: number = '100000' as any
as const
將值視為不可變的常量,而不是可變的變數
const name = 'lybenson' as const
name
類型是 'lybenson'
, 而不是 string
如果是對象類型:
const user = {
name: 'lybenson',
age: 18
} as const
不使用 as const
時,user
的類型會被推導為
const user: {
name: string
age: number
}
使用 as const
後,user
的類型會被推導為
const user: {
readonly name: 'lybenson'
readonly age: 18
}
<T>
#
T
是需要轉換的類型
const distance: number = <any>'100000'
內置類型聲明#
內置類型可以幫助我們更方便的定義類型,例如 Omit
可以剔除對象的屬性
interface User = {
name: string
age: number
sex?: number
salary: number
workTime: number
}
// Student 類型是 User 類型去除了字段 salary 和 workTime 後的類型
type Student = Omit<User, 'salary' | 'workTime'>
完整見下表
類型名 | 說明 |
---|---|
Partial<T> | 將 T 中所有屬性變為可選 |
Required<T> | 將 T 中所有屬性變為必選 |
Readonly<T> | 將 T 中所有屬性變為只讀 |
Pick<T, K extends keyof T> | 從 T 中選擇一組屬性,選擇的屬性在 K 中 |
Record<K extends keyof any, T> | 構造一個屬性名類型為 K , 屬性類型為 T 的對象類型。如type obj = Record<string, any> |
Exclude<T, U> | 從聯合類型 T 中剔除包含在 U 中的類型 |
Extract<T, U> | 從聯合類型 T 中提取包含在 U 中的類型 |
Omit<T, K extends keyof any> | 從 T 中剔除在 K 中的屬性 |
NonNullable<T> | 從類型 T 中排除 null 和 undefined |
Parameters<T extends (...args: any) => any> | 從函數類型 T 中提取參數類型,並返回一個由參數類型組成的元組類型 |
ReturnType<T extends (...args: any) => any> | 從函數類型 T 中提取並返回函數的返回值類型 |
InstanceType<T extends abstract new (...args: any) => any> | 從構造函數類型 T 中提取並返回構造函數實例的類型 |
Uppercase<S extends string> | 將字串類型 S 中的所有字符轉換為大寫字母,並返回一個新的字串類型 |
Lowercase<S extends string> | 將字串類型 S 中的所有字符轉換為小寫字母,並返回一個新的字串類型。 |
Capitalize<S extends string> | 將字串類型 S 的第一個字符轉換為大寫字母 |
Uncapitalize<S extends string> | 將字串類型 S 的第一個字符轉換為小寫字母 |
ThisType<T> | 指定方法中 this 關鍵字的類型 |