TS新增了一個重要概念:接口,分爲對象類型接口和函數類型接口
接口能夠約束對象,函數,類的結構和類型,是一種代碼協做必須遵照的契約
接口的定義方式:後端
使用interface關鍵字
對象類型接口
接口中可定義 肯定屬性、可選屬性、任意屬性、只讀屬性數組
interface UserInfo { name: string; age: number; } const myInfo: UserInfo = { name: "haha", age: 20 };
接口中約束好的肯定屬性,定義對象變量的時候 不能少也 不能多函數
二、可選屬性spa
interface UserInfo {
name: string;
age: number;
sex?:string
}
const myInfo: UserInfo = {
name: "haha",
age: 20
};
接口中的可選屬性,是表示在對象變量中能夠不存在code
三、任意屬性對象
interface UserInfo {
name: string;
age: number;
sex?:string ;
[propName: string]:any;
}
const myInfo: UserInfo = {
name: "haha",
age: 20,
test1: 'lala',
test2: 'ff',
test3:123
};
注:一旦定義了任意屬性,那麼肯定屬性和可選屬性的類型都必須是任意屬性類型的子類;blog
定義了任意屬性後,對象變量中的屬性個數才能夠出現比接口的屬性數量多的狀況索引
四、只讀屬性接口
interface UserInfo {
readonly id: number;
name: string;
age: number;
sex?: string;
[propName: string]: any;
}
const myInfo: UserInfo = {
id: 1,
name: "haha",
age: 20,
test1: "lala",
test2: "ff",
test3: 123
};
只讀屬性也是肯定屬性,在對象變量定義的時候必須有值,此後不能修改ip
以查詢商品列表接口API爲例:
// 接口聲明:API協議約定返回格式 interface ResponseData { resCode: number; resData: ResultData[]; message: string; } // 數據接口聲明 interface ResultData { productId: number; productName: string; }
符合接口約定的對象:
let resultData = { resCode: 0, resData: [ { productId: 1, productName:"TypeScipt實戰" }, { productId: 2, productName:"TypeScipt從入門到精通" }, ], message: "success" }
輸出函數對結果進行打印:
function render(res: ResponseData) { console.log(res.resCode, res.message) res.resData.forEach((obj) => { console.log(obj.productId, obj.productName) }) } render(resultData);
輸出:
0 "success" 1 "TypeScipt實戰" 2 "TypeScipt從入門到精通"
額外屬性
在接口的實際調用中,後端也常常會傳遞約定以外的字段,好比:
let resultData = { resCode: 0, resData: [ { productId: 1, productName:"TypeScipt實戰", remark:""}, // 接口約定之外的remark字段 { productId: 2, productName:"TypeScipt從入門到精通" }, ], message: "success" }
此時,並無報錯,TS容許這種狀況的發生
只要傳入的對象知足接口的必要條件就能夠被容許,即便傳入多餘的字段也能夠經過類型檢查
但也有例外,若是直接傳入對象字面量,TS就會對額外的字段進行類型檢查
如下方式會報錯:
render({
resCode: 0, resData: [ { productId: 1, productName:"TypeScipt實戰", remark: "備註"}, { productId: 2, productName:"TypeScipt從入門到精通" }, ], message: "success" })
繞過檢查的方法有3種:
將對象字面量賦值給一個變量後,在render再也不報錯:
let result = { resCode: 0, resData: [ { productId: 1, productName:"TypeScipt實戰", remark: "備註"}, { productId: 2, productName:"TypeScipt從入門到精通" }, ], message: "success" } render(result)
使用類型斷言方式,明確告訴編譯器類型是什麼,編譯器就會繞過類型檢查
方法1:
object as targetInterface
render({ resCode: 0, resData: [ { productId: 1, productName:"TypeScipt實戰", remark:""}, { productId: 2, productName:"TypeScipt從入門到精通" }, ], message: "success" } as ResponseData)
方法二:
<targetInterface>object
render(<ResponseData>{ resCode: 0, resData: [ { productId: 1, productName:"TypeScipt實戰", remark: "備註"}, { productId: 2, productName:"TypeScipt從入門到精通" }, ], message: "success" })
添加字符串索引簽名:
interface ResultData { productId: number; productName: string; [remark: string]: any; // 字符串索引簽名 }
表示用任意字符串去索引List,可獲得任意結果,此時List能夠實現支持多個屬性
1,在TS中,可使用一個變量直接定義函數:
// 1,使用變量定義函數 let add: (x: number, y: number) => number
= (x, y){
return x+y; };
add(1,2)
2,還可使用接口來定義函數:
// 2,使用接口定義函數 interface Add { (x: number, y: number): number }
let myFunc: Add = function(x, y){ return x+y; }; myFunc(1,2);
3,使用類型別名來定義函數:
類型別名使用type關鍵字,至關於爲函數類型起一個名字
// 3,使用類型別名來定義函數 type Add = (x: number, y: number) => number
當不能肯定接口中有多少個屬性時,可使用可索引類型接口 可索引類型接口能夠用數字去索引,也能夠用字符串去索引
聲明一個數字索引類型的接口:
表示用任意數字去索引numberIndex都會獲得一個string
interface numberIndex { [x: number]: string } // 至關於聲明瞭一個字符串類型的數組 let chars: numberIndex = ['A', 'B']
聲明一個字符串索引類型的接口:
表示用任意的字符串去索引stringIndex獲得的結果都是string
interface stringIndex {
[x: string]: string
}
這樣聲明後,就不能聲明number類型的成員了,會報錯
interface stringIndex { [x: string]: string y: number;// Property 'y' of type 'number' is not assignable to string index type 'string'. }
在上邊的字符串索引接口stringIndex中,添加數字索引簽名
interface stringIndex {
[x: string]: string
[z: number]: string
}
這樣作.接口既能夠用數字索引Names也能夠用字符串索引Names
但須要注意:數字索引的返回值,必定要是字符串返回類型的子類型
這是由於JS會進行類型轉換,將number轉換成string,這樣就能保證類型的兼容性
好比:將數組索引的返回值改爲number:
interface stringIndex { [x: string]: string [z: number]: number // // Numeric index type 'number' is not assignable to string index type 'string'. }
這樣就和String類型不兼容了,要取一個可以兼容number的類型,好比any:
interface stringIndex { [x: string]: any [z: number]: number // Numeric index type 'number' is not assignable to string index type 'string'. }