typescript筆記-高階型別
阿新 • • 發佈:2020-08-24
一、交叉型別(&): 將多個型別合拼在一起
1 // 示例1 2 type I0 = {TOP:"TOP"};//使用type宣告的字面量型別 3 interface I1 { 4 name:string 5 sleep:()=>void 6 } 7 interface I2 { 8 name:string 9 working:()=>void 10 } 11 12 type I3 = I1&I2&I0 13 let O1:I3 = { //合拼的所有成員型別不能少也不能多 14 name:"121", 15 sleep(){},16 working(){}, 17 TOP:"TOP", 18 } 19 20 // 示例2 21 function Extend<T,U>(first:T,second:U):T&U{ 22 let res = <T&U>{} ;//正確 23 // let res:T&U;//正確 24 //let res = {} as T&U; //正確 25 // let res = {};// 沒指定型別。報錯 26 for (let key in first) { 27 (<any>res)[key] = first[key];//需要使用斷言,否則報型別錯誤 28 } 29 for (let key in second) { 30 if (Object.prototype.hasOwnProperty.call(res, key)) { 31 (<any>res)[key] = second[key] 32 } 33 } 34 return res 35 } 36 let oj1 = {a:1} 37 let oj2 = {a:2,b:1} 38 let ro = Extend(oj1,oj2)
二、聯合型別( | ): 指定多個型別,多選一
1 interface I1 { 2 name:string 3 sleep:()=>void 4 } 5 type I4 = I1|I2|'LEFT'|'TOP'|'RIGHT'|'BUTTOM' 6 7 let O2:I4 = "BUTTOM" ;// 這裡選了字面量型別 BUTTOM 8 let O3:I4 = { // 這裡選了I1 型別 9 name:"ds", 10 sleep(){} 11 }
三、類型別名 type
1. 只是給型別起一個名字,不會建立型別
2. 類型別名與介面區別,滑鼠懸浮在型別上會顯示字面量型別,而介面只會顯示Interface
3. 類型別名不能別 extends和implements
1 type T1=string //原始型別 2 3 type2 T2 = { // 物件型別 4 name:string, 5 age:number 6 } 7 8 type T3 = "success" ||"fail" ;// 字面量型別
四、 獲取值的型別 / 型別保護 typeof
1 // 示例1:獲取資料型別 2 let O4 = {name:"lily",age:12} 3 type I4 = typeof O4 4 5 class O5 { 6 uid:number|null=null 7 constructor(){} 8 getName(){} 9 getAge(){} 10 11 } 12 let obj = new O5() 13 type I6 = typeof obj 14 15 // 示例2:做型別保護判斷 16 function fn1(data:string|number){ 17 if(typeof data==="string"){ 18 // dosomething 19 }else if(typeof data==="number"){ 20 // dosomething 21 } 22 }
五、限制類型的屬性選項keyof
1 //示例1 2 type I1 ={ 3 id:number 4 name:string 5 age:number 6 } 7 type I2 = keyof I1;// 獲取到I1的型別屬性key(是一個聯合型別):id|name|age 8 9 10 //示例2: 11 // 原來寫法 12 function getValue(obj:any,key:string){ 13 return obj[key] 14 } 15 getValue({name:"limk"},"id");//如果獲取的值不存在,不會有任何提示 16 17 //限制類型寫法 18 function getVlaueH<T>(obj:T,key:keyof T){ 19 return obj[key] 20 } 21 getVlaueH({name:"mike"},"name");// 如果第二引數的key 不存在第一個引數的物件中就會報型別錯
六、對映型別:keyof+in
簡單實現利用keyof+in 將可選型別變成必要型別
1 type person = { 2 name:string, 3 age?:number, 4 id:number 5 } 6 type Readolys<T>={ 7 [k in keyof T]-?:T[k] 8 } 9 let pser:Readolys<person> = { 10 name:"mike", 11 age:1, 12 id:1 13 }
七:條件型別:條件型別指由表示式所決定的型別
1 // 示例,常見寫法 2 T extends U?T:U ;// 如果T 型別 屬於 U型別,則返回T 型別,否側返回U型別 3 4 示例: 5 let dataType = "TOP"|"LEFT"|"BUTTOM"|"RIGHT" 6 type Ttype<T,U> = T extends U?true:false 7 type res1 = Ttype<"TOP",dataType>;// true 8 type res2 = Ttype<"fail",dataType>;// false
八、 型別斷言與保護
(1.) 當你確定知道某個值的型別,ts可能在型別中檢測不到,你就可以使用斷言確定該值的型別
(2.)官網說有兩種寫,一個是as,一個是尖括號<型別>值,在typescript中的tsx只支援as斷言寫法,還有一個 is
(8.1) as
//這裡獲取元素,ts會檢測有可能不存在,你可以指定是它一定存在指定型別 let div = document.getElementById("div") as HTMLDivElement;//HTMLDivElement;
(8.2) <型別>值:這裡尖括號<>不要和泛型搞亂了,泛型是在變數前<>;斷言是對值重新宣告型別,<>在值的前面
1 let str = "this is string"; 2 let len = (<string>str).length
(8.3)is :自定義型別保護,一般在函式引數中用,用來判斷某個屬性屬性某個型別
1 //示例1 2 function isString(s:unknown):s is string{ 3 return typeof s ==="string" 4 } 5 //示例2 6 type Fish = { 7 swim:()=>void 8 } 9 type Bird = { 10 fly:()=>void 11 } 12 function isFish<T>(pet: Fish | Bird): pet is Fish { 13 return (<Fish>pet).swim !== undefined; 14 }
九、通過索引訪問型別的自型別
1 let I1 = { 2 id:1, 3 name:"name1", 4 childs:[ 5 {id:2,name:"name2",childs:[]} 6 ] 7 } 8 type I2 = typeof I1 9 let O8:I2['childs'] = [{id:1,name:"like",childs:[]}]