一文說明白,TypeScript 的接口

●?通過前兩章的學(xué)習, 我們基本上對于 TS 已經(jīng)入門了
●?但是我們會發(fā)現(xiàn), 我們好像對于類型限制還缺少了一些內(nèi)容
●?這一張我們繼續(xù)學(xué)習
接口
●?初學(xué)者剛一聽到這個名字, 可能不太好理解
●?接觸過前后端交互的可能會對這個名字比較迷茫, 容易混亂
●?但是, 都不要糾結(jié), 忘記你直接所有的一切, 他就是一個名字而已

●?就像這個玩意, 老婆餅, 老婆在哪里, 就是個名字而已
●?那么接口到底是干什么的呢 ?
○?其實就是一個用來限制非基本數(shù)據(jù)的類型限制手段而已
●?我們回憶之前的類型限制, 我們發(fā)現(xiàn)
○?對于 對象, 函數(shù), 類 等內(nèi)容并沒有很好的限制方式
○?難道真的沒有, 并不是
○?接口就是其中一個
接口初體驗
●?來看下面這個例子

●?所以這一段代碼就會提示錯誤

●?那么我們就需要修改代碼, 賦值的時候需要有一個 name 屬性存在
●?這樣就沒有問題了
●?再繼續(xù)看下一個例子
●?我們會發(fā)現(xiàn) user 變量和 person 變量的類型限制使用的是一模一樣的內(nèi)容
○?但是我需要逐次書寫
○?按照我們程序員的懶惰特點來看, 這個東西為什么不能只寫一遍呢 ?
○?一定是可以的
●?這個東西就叫做 接口
○?我們可以把這一種類型限制, 拿出來寫成一個接口
○?用起來就方便多了
●?接口的形式書寫
○?interface : TS 中定義接口的關(guān)鍵字
○?Info : 接口名稱( 建議首字母大寫 )
●?是不是一下子豁然開朗了

接口的各類屬性
基礎(chǔ)接口屬性
●?就是對接口內(nèi)的各種屬性進行數(shù)據(jù)類型限制
●?這個接口就是一個基礎(chǔ)接口限制
○?必須包含一個 name 屬性, 而且是 string 類型
○?必須包含一個 age 屬性, 而且是 number 類型
○?必須包含一個 gender 屬性, 而且是 boolean 類型
○?必須包含一個 hobby 屬性, 而且是由 string 組成的數(shù)組
選填屬性
●?我們可以設(shè)置一些屬性選填
●?這里就是設(shè)置了一個可選屬性
○?city 屬性可有可無, 如果添加了 city 屬性, 必須是 string 類型


只讀屬性
●?我們也可以設(shè)置一些屬性不允許被修改
●?就需要在接口內(nèi)寫屬性的時候, 用到 readonly 關(guān)鍵字
●?這樣定義完畢以后, nationality 屬性值定義好以后就不能修改了

額外屬性
●?到這里我們會發(fā)現(xiàn)一個問題
○?那就是我要是用接口限制一個數(shù)據(jù), 那么必須要把所有可能會出現(xiàn)的屬性都寫上
○?但是萬一我只能確定部分屬性, 其他的不確定怎么辦呢
●?這個時候可以用到額外屬性
●?這就表示, 除了這里已經(jīng)列出來的屬性, 還可以添加其他的鍵值對
○?但是 key 必須是字符串類型
○?值可以是任意類型
●?這個額外屬性其實也不太建議使用
○?第一: 我們最好準確的把握我們自己寫的數(shù)據(jù)類型限制
○?第二: 這樣一來, 我們的限制其是意義就并不是很大了

索引型接口
●? 索引型接口一般就是用接口去約束一個數(shù)組
●?我們先來分析這個接口
○?用的是額外屬性的方式
○?可以添加任意個屬性
○?但是 key 必須是一個 number 類型
■?如果是對象數(shù)據(jù)結(jié)構(gòu), 那么key 只能是 string 類型
■?數(shù)組數(shù)據(jù)類型, key 才是 number 類型
○?值必須是一個 string
●?所以這個接口就限制了必須是一個由字符串組成的數(shù)組

●?其實這個就等價于我們限定數(shù)組的方式是一樣的
函數(shù)接口
●?我們思考一下, 其實對于函數(shù)的限定無非就是兩個部分
○?參數(shù)
○?返回值
●?所以一個函數(shù)接口就是限制好函數(shù)的參數(shù)和返回值就好了
●?分析一波
○?這個限制了需要有兩個參數(shù)
■?一個是 number 類型
■?一個是 string 類型
○?還限制了返回值
■?必須是 string 類型
○?那么這種數(shù)據(jù)類型, 就肯定是函數(shù)了
●?但是這種接口一般用來限制 函數(shù)表達式
○?對于聲明式函數(shù)不適用


接口繼承
●?接口也是可以實現(xiàn)繼承的
●?同樣是使用 extends 關(guān)鍵字

類接口
●?我為什么把 類接口 放在最后面呢, 因為他非常復(fù)雜

類的觀察和分析
●?咱們先來寫一個簡單的類分析一下
●?咱們來看一下, 如何才能對一個類做出限制
○?限制好調(diào)用必須和 new 關(guān)鍵字連用
○?類里面有一個 constructor 構(gòu)造器, 需要接受參數(shù)并且限定返回的實例是一個什么樣的對象
○?我們調(diào)用這個類的時候傳遞多少個參數(shù), 分別是什么類型
○?類的原型上有多少個方法
●?需要這么多維度才能限制好一個類類型數(shù)據(jù)
類接口
●?首先, 我們先要來學(xué)習一個新的接口規(guī)范, 就叫做類接口
●?類接口是專門給類使用的
●?先來看一下
●?給一個類使用接口, 需要使用 implements 關(guān)鍵字
●?看上去好像很好的樣子, 也很簡單的嘛

●?但是寫完才發(fā)現(xiàn), 全是錯誤

●?我來幫你分析一下
○?StudentConstructor 接口, 看似是一個類接口, 但是其實只是限制了 new 關(guān)鍵字 和 返回值類型, 不能說他是一個類, 更像是一個函數(shù), 所以我們那它去限制一個類顯然不太好
○?Student 這個類, 不是函數(shù), 是一個類, 里面的 constructor 才是一個構(gòu)造器函數(shù), 那么這個構(gòu)造器在沒有被調(diào)用的時候, 是沒有實例的, 所以你沒辦法合理添加 name 和 age 屬性
●?全都是問題, 那我怎么辦

●?這個時候, 我們要想更好的做出所有限制, 就需要借助工廠函數(shù)
○?并且還需要兩個接口
○?一個限制實例對象
○?一個限制構(gòu)造器
●?先不著急加入 TS 限制, 先把類寫成工廠模式
●?也就是說, 我們需要把類放進工廠函數(shù)內(nèi)去調(diào)用即可
○?我們的工廠函數(shù)需要接受一個 類, 并且還要接受這個類需要的 參數(shù)
○?在工廠函數(shù)內(nèi)進行實例化操作, 然后返回來
●?接下來我們就可以加上接口限制了
○?工廠函數(shù)的 ctro 參數(shù), 必須要是一個滿足 StudentConstructor 接口的類
○?工廠函數(shù)的返回值必須是一個滿足 StudentInstance 接口的實例對象
○?通過這兩點, 就限制了類的實例對象有的成員, 多了就不行
■?因為工廠函數(shù)只能接受這些數(shù)據(jù)
■?多了的話, 調(diào)用工廠函數(shù)就會出錯了
●?最后書寫類
●?這時候, 一個真正的對類的限制就完成了
●?確實是非常麻煩, 所以我們在開發(fā)過程中相對比較少的對 類進行 限制
●?因為類其實本身就是一種限制