Typescript - 通俗易懂的 interface 接口,創建接口 / 基礎使用 / 可選屬性 / 只讀屬性 / 任意屬性(詳細教程)

前言

在面向對象語言中,接口是一個很重要的概念,它是對行為的抽象,而具體如何行動需要由類去實現。

TypeScript 中的接口是一個非常靈活的概念,除了可用于 對類的一部分行為進行抽象 以外,也常用于對「對象的形狀(Shape)」進行描述。

?TypeScript 的核心原則之一是對值所具有的結構進行類型檢查,并且只要兩個對象的結構一致,屬性和方法的類型一致,則它們的類型就是一致的。? 在TypeScript里,接口的作用就是為這些類型命名和為代碼或第三方代碼定義契約。

簡單點說,在 TypeScript中,接口是一個很重要的特性,它讓 TypeScript 具備了 JavaScript 所缺少的、描述較為復雜數據結構的能力。

引入主題

其實在 JavaScript 日常開發中,很多時候都需要接口來 “規范” 程序。

假設在 JavaScript 中定義一個函數,用來獲取一個用戶的姓名和年齡的字符串:

function getUserInfo(user) {return `name: ${user.name}, age: ${user.age}`
}

函數調用:

getUserInfo({name: "koala", age: 18})

您可能會問,我們寫 JavaScript 的時候,這個再正常不過了吧?

但請注意,如果這個 getUserInfo() 在多人開發過程中,如果它是個公共函數(多個開發者都會調用),如果不是每個人點進來看函數對應注釋,可能會出現以下錯誤的調用:

// 1: 直接調用,不知道還需要傳參數
getUserInfo() // Uncaught TypeError: Cannot read property 'name' of undefined// 2: 只傳遞一個參數,不知道還有其他參數
console.log(getUserInfo({name: "王佳斌"})) // name: 王佳斌, age: undefined// 3: 參數知道傳遞多少個,但不知鍵名
getUserInfo({name: "王佳斌", width: 560}) // name: 王佳斌, age: undefined// ...

由于 JavaScript 是弱類型的語言,所以 并不會對我們傳入的代碼進行任何的檢測

😦 有些錯你自己都說不清楚,但是就出了問題。


那么如何解決呢?有請 Typescript 接口登場。

創建接口

指定的接口名稱,最好與普通變量名 “有所區分” ,比如接口名首字母大寫、首字母前綴(In_xxx)等。

在 Typescript 中,使用 interface 關鍵字來定義一個接口,其中 name 就是接口名稱。

interface name {}

基礎使用

Typescript 接口可以規定函數的 “形狀”,也可以規定變量的 “形狀”,下面有兩個示例。

以下 JavaScript 例子(前面已經提到了,忘記的話往前翻):

function getUserInfo(user) {return `name: ${user.name}, age: ${user.age}`
}

這個所存在的問題大家已經知道了,下面用 Typescript 接口進行函數重構。

// 規定"形狀"
interface Info {name: string;age: number;
}// 函數(冒號后跟上 "接口名")
function getUserInfo({ name, age }: Info) {return `name: ${name}, age: ${age}`
}// 正常都傳遞
console.log(getUserInfo({ name: '王佳斌', age: 123 }))
// 結果OK:"name: 王佳斌, age: 123" // 少傳遞一個
console.log(getUserInfo({ name: '王佳斌' }))
// Property 'age' is missing in type '{ name: string; }' but required in type 'Info'.
// 類型“{name:string;}”中缺少屬性“age”,但類型“Info”中需要該屬性。// 都不傳遞
console.log(getUserInfo())
// Expected 1 arguments, but got 0.
// 應為1個參數,但得到了0個。

你看,這些都是在編寫代碼時 TypeScript 提示的錯誤信息,這樣就避免了在使用函數的時候傳入不正確的參數。

注意:在定義接口時,不要把它理解為是在定義一個對象{} 括號包裹的是一個代碼塊,里面是聲明語句,只不過聲明的不是變量的值而是類型。聲明也不用等號賦值,而是冒號指定類型。每條聲明之前用換行分隔即可,也可以使用分號或者逗號。


另外,接口還可以被變量所使用(繼承接口的 “形狀”),如下代碼所示:

// 規定"形狀"
interface Info {name: string;age: number;
}// 變量 "繼承" 接口
const student: Info = {name: '小王',age: 15
}// 測試變量
console.log(student)//{"name": "小王", "age": 15}// 錯誤用法(比如寫一個 "Info" 接口不存在的參數)
const err: Info = {a: 1
}
// Object literal may only specify known properties, and 'a' does not exist in type 'Info'.
// 對象文字只能指定已知的財產,類型“Info”中不存在“a”。

可選屬性

當然,TypeScript 中也允許不 “必傳” 某些參數,有這個字段就做處理,沒有就忽略。

如下代碼所示,message 參數可以不傳遞。

// 使用 "?" 表示此參數非必傳
interface Log {message?: string;
}// 函數
function print({ message }: Log) {console.log(message || '該參數沒有傳遞~')
}// 傳遞參數
print({ message: 'hello' }) //"hello" // 不傳遞
print({}) //"該參數沒有傳遞~" 

很好理解。

只讀屬性

TypeScript 支持將某些參數設置為 “只讀”,用于限制只能在對象剛剛創建的時候修改其值,后續無法再修改。

如下代碼所示,age 參數不可后期修改。

// 使用 "readonly" 關鍵字表示此參數"只讀"
interface Info {name: string;readonly age: number;
}// 創建變量("age"只能初始的時候賦值一次)
const student: Info = {name: '小王',age: 15
}// 測試修改只讀屬性 "age"
student.age = 50
// Cannot assign to 'age' because it is a read-only property.
// 無法分配給“age”,因為它是只讀屬性。

此外 TypeScript 還提供了 ReadonlyArray<T> 類型,它與 Array<T> 相似,只是把所有可變方法去掉了,因此可以確保數組創建后再也不能被修改。

// 創建一個 "絕對不可修改" 的數組(number類型)
let arr: ReadonlyArray<number> = [1, 2, 3, 4]// 測試賦值
arr[0] = 10
// Index signature in type 'readonly number[]' only permits reading.
// 類型為“只讀數字[]”的索引簽名只允許讀取。// 測試添加數組項
arr.push(5)
// Property 'push' does not exist on type 'readonly number[]'.
// 類型“只讀數字[]”上不存在屬性“push”。// 測試賦值數組長度
arr.length = 99
// Cannot assign to 'length' because it is a read-only property.
// 無法分配給“length”,因為它是只讀屬性。

任意屬性

有時候我們希望一個接口中除了包含必選和可選屬性之外,還允許有其他的任意屬性,這時我們可以使用 索引簽名 的形式來滿足上述要求。

如下代碼所示,除了 name 必傳外,后面你可以隨意傳遞參數。

// 使用 "[propName: string]: any" 支持任意類型
interface Person {name: string;[propName: string]: any;
}// 只傳遞必填,其他參數不要
const a: Person = { name: '小王' }
console.log(a) //{"name": "小王"}// 傳遞必填,其他參數隨意傳遞
const b: Person = { name: '小王', age: 15, sex: '男' }
console.log(b) //{"name": "小王", "age": 15, "sex": "男"}

很好理解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/96376.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/96376.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/96376.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【硬件-筆試面試題-92】硬件/電子工程師,筆試面試題(知識點:米勒效應,米勒平臺)

題目匯總版--鏈接&#xff1a; 【硬件-筆試面試題】硬件/電子工程師&#xff0c;筆試面試題匯總版&#xff0c;持續更新學習&#xff0c;加油&#xff01;&#xff01;&#xff01;-CSDN博客 【硬件-筆試面試題-92】硬件/電子工程師&#xff0c;筆試面試題&#xff08;知識點…

C語言深度入門系列:第十一篇 - 動態內存管理與數據結構:程序世界的高效算法大師

C語言深度入門系列&#xff1a;第十一篇 - 動態內存管理與數據結構&#xff1a;程序世界的高效算法大師 本章目標 本章將深入探討C語言中的動態內存管理和經典數據結構實現&#xff0c;這是從基礎編程邁向算法工程師的關鍵一步。您將掌握內存的精確控制、理解各種數據結構的本質…

Go 語言開發環境安裝與 GOPROXY 鏡像配置(含依賴管理與版本切換技巧)

在國內搭建 Go 開發環境的最大障礙不是“怎么裝”&#xff0c;而是“下不動”。本文是我在多臺 Windows / macOS / Linux 機器上踩坑后的整合筆記&#xff1a;用最穩妥的安裝方式 合理的鏡像配置 一套通吃的依賴/版本管理流程&#xff0c;把速度、穩定性和可維護性一次性解決…

崔傳波教授:以科技與人文之光,點亮近視患者的清晰視界?

崔傳波教授&#xff1a;以科技與人文之光&#xff0c;點亮近視患者的清晰視界?在臨沂新益民眼科醫院&#xff0c;有這樣一位眼科醫師——他不僅是近視矯正領域的專家&#xff0c;更是“金視青春之光手術”的研發倡導者。?崔傳波教授?以其深厚的學術功底、創新的技術理念和以…

如何寫過濾條件wrapper的使用

模糊查詢 &#xff1a;功能是&#xff1a;查詢 WORK_NUM 字段包含 ${workOrder.workNum} 的記錄。<if test"workOrder.workNum ! null and workOrder.workNum ! ">and b.WORK_NUM like CONCAT(%,CONCAT(#{workOrder.workNum},%)) </if>一、比較條件方法示…

【Spring Boot 報錯已解決】徹底解決 “Main method not found in class com.xxx.Application” 報錯

文章目錄引言一、問題描述1.1 報錯示例1.2 報錯分析1.3 解決思路二、解決方法2.1 方法一&#xff1a;添加標準的main方法2.2 方法二&#xff1a;檢查main方法的定義是否規范2.3 方法三&#xff1a;檢查主類的位置是否正確2.4 方法四&#xff1a;重新構建項目并清理緩存三、其他…

配置自簽證書多域名的動態網站+部署http的repo倉庫+基于nfs與yum倉庫的http部署

1.配置自簽證書多域名的動態網站1.1配置自簽證書1.1.1配置倉庫[rootapache ~]# vim /etc/yum.repos.d/epel.repo [epel] nameepel baseurlhttps://mirrors.aliyun.com/epel/9/Everything/x86_64/ gpgcheck0 1.1.2安裝easy-rsa工具(用于生成和…

【開題答辯全過程】以 12306候補購票服務系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

計算機畢業設計 基于深度學習的酒店評論文本情感分析研究 Python畢業設計項目 Hadoop畢業設計選題 機器學習選題【附源碼+文檔報告+安裝調試】

博主介紹&#xff1a;?從事軟件開發10年之余&#xff0c;專注于Java技術領域、Python、大數據、人工智能及數據挖掘、小程序項目開發和Android項目開發等。CSDN、掘金、華為云、InfoQ、阿里云等平臺優質作者? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&…

嵌入式第五十二天(GIC,協處理器,異常向量表)

一.GICGIC&#xff08;Generic Interrupt Controller&#xff0c;通用中斷控制器&#xff09; 是ARM架構中管理系統中斷的核心組件&#xff0c;負責接收、優先級排序、分發中斷信號給處理器核心。其核心功能和關鍵版本如下&#xff1a;核心功能1. 中斷接收與分發&#xff1a;接…

基于hiprint的票據定位打印系統開發實踐

基于hiprint的票據定位打印系統開發實踐 在日常的Web開發中&#xff0c;我們經常需要實現打印功能&#xff0c;特別是對于票據、標簽等需要精確排版的打印需求。今天我將分享一個基于hiprint插件實現的票據定位打印系統&#xff0c;重點介紹如何實現單行打印、批量打印以及金額…

Android ScrollView嵌套RecyclerView 導致RecyclerView數據展示不全問題

Android RecyclerView 數據展示不全問題&#xff08;ScrollView→NestedScrollView 修復&#xff09; 一、問題核心現象 布局初始結構&#xff1a;外層用ScrollView包裹包含兩個CustomBlogCardView&#xff08;內部均含RecyclerView&#xff09;的LinearLayout。 異常表現&…

AI助力數學學習,輕松掌握知識點!

小伙伴們&#xff0c;今天我們來利用AI輔助數學學習&#xff0c;將數學題目提交給AI,經過分析后給出相應的解題思路和知識點分析。現在有了AI這個"智能小老師"&#xff0c;學習變得更輕松&#xff01;只需把題目交給它&#xff0c;AI就能快速分析題目類型&#xff0c…

AI-調查研究-76-具身智能 當機器人走進生活:具身智能對就業與社會結構的深遠影響

點一下關注吧&#xff01;&#xff01;&#xff01;非常感謝&#xff01;&#xff01;持續更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持續更新中&#xff01;&#xff08;長期更新&#xff09; AI煉丹日志-31- 千呼萬喚始出來 GPT-5 發布&#xff01;“快的…

機器學習、深度學習

卷積神經網絡&#xff08;CNN&#xff09;vs. 循環神經網絡&#xff08;RNN&#xff09;vs. Transformer 一文帶你搞懂 AI Agent 開發利器&#xff1a;LangGraph 與 LangChain 區別 大語言模型&#xff1a;基于LLM的應用開發框架「LangChain」最全指南

SQL語句執行時間太慢,有什么優化措施?以及衍生的相關問題

SQL語句執行時間太慢&#xff0c;有什么優化措施&#xff1f; 可以從四個方面進行&#xff1a; 第一個是查詢是否添加了索引 如果沒有的話&#xff0c;為查詢字段添加索引&#xff0c; 還有是否存在讓索引失效的場景&#xff0c;像是沒有遵循最左前綴&#xff0c;進行了一些…

QtConcurrent應用解析

目錄 對比傳統線程 1. QtConcurrent::run() —— 異步運行函數 2.QtConcurrent::mapped() —— 并行轉換 3. QtConcurrent::filter() —— 并行過濾 4. QtConcurrent::run() QFutureWatcher —— UI 異步更新 5.線程池配置 QtConcurrent 是 Qt 框架提供的一個 高級并發編…

大疆圖傳十公里原理:無人機圖傳技術解析

大疆圖傳系統的核心在于把發射端的能量、機載接收的靈敏度、以及環境中的衰減因素&#xff0c;進行科學的預算與動態的修正。簡單的說&#xff0c;就是通過精準的鏈路預算來確保在最壞環境下仍有可用的信號空間。發射功率、天線增益、空中與地面的路徑損耗、接收端的噪聲底線等…

jmeter 帶函數壓測腳本

包含時間戳獲取、md5值計算、隨機字符串獲取<?xml version"1.0" encoding"UTF-8"?> <jmeterTestPlan version"1.2" properties"5.0" jmeter"5.6.3"><hashTree><TestPlan guiclass"TestPlanGui&…

鴻蒙app日志存儲

app的pid獲取 import process from @ohos.process;@Entry @Component struct MainAbility {aboutToAppear(): void {console.log(this.TAG,"pid: "+process.pid)}} 獲取本應用日志 在Android中可以使用logcat --pid xxxx 獲取特定進程xxxx的打印日志 在鴻蒙中也有…