在TypeScript中,為了可以約束對象定義,提供了兩個新的特性,接口和類型別名。
TypeScript中的接口
在強類型語言中,都有接口的概念,那么TypeScript中的接口是如何使用的呢?
接口定義形式如下:
interface test {
name: string,
value: number
}
上述接口,定義了一個test接口,該接口可以約束兩個字段的數據類型,分別是name和value。而接口的使用主要有三個方面:實現、繼承和約束。
實現接口
通過用類來實現接口,就實現了接口約束類中必須定義的字段,實現接口的關鍵字是implements,接下來,我們定義一個類來實現上述接口:
class TestClass implements test {
name: string;
value: number;
}
如果類中缺少了屬性name和value,就會報錯,我們就可以用test接口來約束實現接口類中的屬性。
繼承接口
接口之間,還可以進行繼承,用來使得該接口擁有被繼承接口的屬性和方法。比如有如下兩個接口:
interface ColorInterface {
color: string;
}
interface LineInterface {
width: number;
}
在上面我們定義了兩個接口,分別表示顏色和線條的寬度,如果我們想要定義一條直線的類別,那么我們可以定義如下接口繼承:
interface StrightLineInterface extends ColorInterface, LineInterface {
height: number
}
此時此刻,接口StrightLineInterface便擁有了color和width屬性,TypeScript中類只能實現一個接口,但是接口可以通過繼承實現多態。
接口約束
除了被實現和繼承,接口還可以用來約束對象或者函數類型。
比如我們后台獲取的數據需要遵循特定類型,我們才能使用,我們就可以用接口來約束我們獲取的數據類型。
比如,我們獲取的數據是一個包含id,name的對象數據,那么我們可以定義如下接口:
interface List {
id: number,
name: string,
age?: number, // 可選屬性表示list中,可有可無的屬性
}
interface Result {
data: List
}
我們在使用result的時候,就可以用Result接口來約束它的格式:
function use(result: Result) {
result.data.map(x => {
// 操作代碼
})
}
接口還可以約束可變參數的對象,可變參數就是我們不知道對象中有多少個屬性,但是我們知道屬性的類別,可以用如下方式約束:
interface NameArray {
[x: number]: string
}
該接口表示我們接受約束的對象必須是數字下標,而值必須是string類型的value對象。
除此之外,接口還可以約束函數:
interface Add {
(x: number, y: number): number
}
let add: Add = (a, b) => a + b;
接口約束Props和State
接口還可以約束React中的Props和State的類型,如下所示:
interface Props {
name: string,
data: string[]
}
interface State {
[x: string]: string
}
class Comp extends React.Component<Props, State> {
// 第一個表示props的類型約束,第二個表示state的類型約束,如果沒有props,我們可以設置為{}
}
類型別名
上面提到的接口可以做的一些事情,而類型別名,主要就是對對象或者函數起到約束作用,特性沒有接口多。
type Add = (x: number, y: number) => number; let add: Add = (a, b) => a + b;
而類型別名是早起TypeScript做類型約束的主要形式,后來引入接口之后,TypeScript推薦我們盡可能的使用接口來規范我們的代碼。
而兩者也都是TSC編譯器做類型判定的時候有作用,我們可以在playground里面看到,當我們寫一個接口或者是一個類型別名定義一個對象或者方法的時候,並未有任何編譯成的es5代碼出現。
總結
這一小節主要講述了類型別名和接口的用法,以及兩者的區別。
TypeScript中,如果再相同功能點的頂一下,推薦使用interface去定義數據類型。
