一. TypeScript類型補充
1. 類型斷言
有時候TypeScript無法獲取具體的類型信息,這個我們需要使用類型斷言(Type Assertions) ,TypeScript只允許類型斷言轉換為 更具體 或者 不太具體 的類型版本,此規則可防止不可能的強制轉換。
符號:as
// 1.類型斷言 as const el = document.getElementById("why") as HTMLImageElement el.src = "url地址" // 2.另外案例: Person是Student的父類 class Person { } class Student extends Person { studying() { } } function sayHello(p: Person) { (p as Student).studying() } const stu = new Student() sayHello(stu)
2. 非空斷言
我們確定傳入的參數是有值的,這個時候我們可以使用非空類型斷言。非空斷言使用的是 ! ,表示可以確定某個標識符是有值的,跳過ts在編譯階段對它的檢測
符號:!
// message? -> undefined | string function printMessageLength(message?: string) { // if (message) { // console.log(message.length) // } // vue3源碼中很多這種寫法 console.log(message!.length) } printMessageLength("aaaa") printMessageLength("hello world")
3. 可選鏈
可選鏈事實上並不是TypeScript獨有的特性,它是ES11(ES2020)中增加的特性:
符號 ?.
它的作用是當對象的屬性不存在時,會短路,直接返回undefined,如果存在,那么才會繼續執行, 雖然可選鏈操作是ECMAScript提出的特性,但是和TypeScript一起使用更版本。

// 定義類型 type Person = { name: string friend?: { name: string age?: number, girlFriend?: { name: string } } } // 聲明對象 const info: Person = { name: "why", friend: { name: "kobe", girlFriend: { name: "lily" } } } // 另外一個文件中 console.log(info.name) // console.log(info.friend!.name) console.log(info.friend?.name) console.log(info.friend?.age) console.log(info.friend?.girlFriend?.name)
4. !!運算符
將一個其他類型轉換成boolean類型;類似於Boolean(變量)的方式;
const message = "Hello World" // const flag = Boolean(message) // console.log(flag) const flag = !!message console.log(flag)
5. ??運算符
它是ES11增加的新特性;
空值合並操作符(??)是一個邏輯操作符,當操作符的左側是 null 或者 undefined 時,返回其右側操作數,否則返回左側操作數 。
let msg1: string | null = 'hello ts'; let msg2: string | null = null; const result1 = msg1 ?? 'hello js'; // 上面等價於 const result2 = msg1 ? msg1 : 'hello js'; console.log(result1); console.log(result2); const result3 = msg2 ?? 'hello js'; // 上面等價於 const result4 = msg2 ? msg2 : 'hello js'; console.log(result3); console.log(result4);
6. 字面量
// 1. 如下,這里聲明的字面量類型為 'hello ts' let msg1: 'hello ts' = 'hello ts'; // msg1='hhh'; //報錯,類型錯誤,因為這里的類型是hello ts //2. 字面量類型的意義, 就是必須結合聯合類型 type Alignment = 'left' | 'right' | 'center' let align: Alignment = 'left' align = 'right' align = 'center'
7. 類型縮小
在給定的執行路徑中,我們可以縮小比聲明時更小的類型,這個過程稱之為 縮小;
常見的類型保護有如下幾種:
A. typeof
B. 平等縮小(比如===、!==)
C. instanceof (檢查一個值是否是另一個值的“實例” )
D. in

// 1.typeof的類型縮小 type IDType = number | string function printID(id: IDType) { if (typeof id === 'string') { console.log(id.toUpperCase()) } else { console.log(id) } } // 2.平等的類型縮小(=== == !== !=/switch) type Direction = "left" | "right" | "top" | "bottom" function printDirection(direction: Direction) { // 1.if判斷 // if (direction === 'left') { // console.log(direction) // } else if () // 2.switch判斷 // switch (direction) { // case 'left': // console.log(direction) // break; // case ... // } } // 3.instanceof 檢查一個值是否是另一個值的“實例” function printTime(time: string | Date) { if (time instanceof Date) { console.log(time.toUTCString()) } else { console.log(time) } } class Student { studying() { } } class Teacher { teaching() { } } function work(p: Student | Teacher) { if (p instanceof Student) { p.studying() } else { p.teaching() } } const stu = new Student() work(stu) // 4. in(用於確定對象是否具有帶名稱的屬性:in運算符,如果指定的屬性在指定的對象或其原型鏈中,則in 運算符返回true;) type Fish = { swimming: () => void } type Dog = { running: () => void } function walk(animal: Fish | Dog) { if ('swimming' in animal) { animal.swimming() } else { animal.running() } } const fish: Fish = { swimming() { console.log("swimming") } } walk(fish)
二. TypeScript函數詳解
1. 函數自身 參數類型 和 返回值類型
// 1. 函數的參數類型 function sum1(num1: number, num2: number) { return num1 + num2; } // 2. 函數的返回值類型 // 添加返回值的類型注解,這個注解出現在函數列表的后面: function sum2(num1: number, num2: number): number { return num1 + num2; } // 和變量的類型注解一樣,我們通常情況下不需要返回類型注解,因為TypeScript會根據 return 返回值推斷函數的返回類型: function sum3(num1: number, num2: number) { return num1 + num2; }
2. 作為參數的函數類型
可以編寫函數類型的表達式(Function Type Expressions),來表示函數類型;
格式為: (n:xx,m:xx)=>xxx, 括號里的是參數名和參數類型,=>后面的是返回值類型,比如: (num1: number, num2: number) => void,代表的就是一個函數類型:
A. 接收兩個參數的函數:num1和num2,並且都是number類型;
B. 並且這個函數是沒有返回值的,所以是void;
// 案例1-函數作為參數進行傳遞 function calc(m1: number, m2: number, fn: (num1: number, num2: number) => number) { return fn(m1, m2); } const result1 = calc(10, 20, function (m, n) { return m - n; }) console.log(result1); const result2 = calc(10, 20, function (m, n) { return m * n; }); console.log(result2); // 案例2--定義常量時, 編寫函數的類型 type myAddFnType = (num1: number, num2: number) => number; const Add1: myAddFnType = (m, n) => { return m + n; } console.log(Add1(10, 20));
3. 參數可選類型
符號:?
可選類型需要在必傳參數的后面
function foo(x: number, y?: number) { if (y) { console.log(x+y); } else { console.log(x); } } foo(20, 30) foo(20)
4. 參數默認值
從ES6開始,JavaScript是支持默認參數的,TypeScript也是支持默認參數的:
格式: 直接 = 號 ,寫上默認值就行了
//通常我們寫的順序: 必傳參數 - 有默認值的參數 - 可選參數 function foo(y: number, x: number = 20, z?:number) { console.log(x, y) } foo(30)
5. 剩余參數
/* @totalNum: 默認初始值 @nums:數組 */ function sum(totalNum: number, ...nums: number[]) { let total = totalNum; for (const num of nums) { total += num; } return total; } console.log(sum(10,100)) console.log(sum(10,100,200)) console.log(sum(10,100,200,300))
6. this的默認推導
// this是可以被推導出來 info對象(TypeScript推導出來) const info = { name: "ypf", eating() { console.log(this.name + " is eating") } } info.eating()
7. this的不明確類型
type ThisType = { name: string }; function eating(this: ThisType, message: string) { console.log(this.name + " eating", message); } const info = { name: "why", eating: eating, }; // 隱式綁定 info.eating("哈哈哈"); // 顯示綁定 eating.call({name: "kobe"}, "呵呵呵") eating.apply({name: "james"}, ["嘿嘿嘿"])
8. 函數重載
function add(num1: number, num2: number): number; // 沒函數體 function add(num1: string, num2: string): string; function add(num1: any, num2: any): any { if (typeof num1 === 'string' && typeof num2 === 'string') { return num1.length + num2.length } return num1 + num2 } const result1 = add(20, 30) const result2 = add("abc", "cba") console.log(result1) console.log(result2) // 在函數的重載中, 實現函數是不能直接被調用的 // add({name: "why"}, {age: 18}) // 實現方式二: 函數的重載 function getLength(args: string): number; function getLength(args: any[]): number; function getLength(args: any): number { return args.length } console.log(getLength("abc")) console.log(getLength([123, 321, 123]))
!
- 作 者 : Yaopengfei(姚鵬飛)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 聲 明1 : 如有錯誤,歡迎討論,請勿謾罵^_^。
- 聲 明2 : 原創博客請在轉載時保留原文鏈接或在文章開頭加上本人博客地址,否則保留追究法律責任的權利。