1. 程式人生 > 實用技巧 >typescript筆記-高階型別

typescript筆記-高階型別

一、交叉型別(&): 將多個型別合拼在一起

 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:[]}]