網(wǎng)站首頁 編程語言 正文
一、定義對(duì)象類型
在TypeScript中定義對(duì)象類型有以下三種方式:
1. 匿名對(duì)象類型
匿名對(duì)象類型是在定義變量時(shí)直接使用花括號(hào){},來定義一個(gè)對(duì)象類型。例如:
const person: { name: string, age: number } = { name: 'John', age: 25 };
上述代碼中定義了一個(gè)person變量,它的類型為對(duì)象,它有兩個(gè)屬性:name和age,其中name屬性的類型為字符串,age屬性的類型為數(shù)字。
2. 接口類型
使用接口來定義對(duì)象類型,可以使代碼更加可讀、易于維護(hù)。例如:
interface Person {
name: string;
age: number;
}
const person: Person = { name: 'John', age: 25 };
上述代碼中,定義了一個(gè)名為Person的接口,其中包括了兩個(gè)屬性:name和age。然后使用Person接口來定義了一個(gè)person變量,它的類型為Person接口。
3. 類型別名
使用類型別名可以為對(duì)象類型定義簡(jiǎn)短、易讀的名稱。例如:
type Person = {
name: string;
age: number;
}
const person: Person = { name: 'John', age: 25 };
上述代碼中,使用type關(guān)鍵字定義了一個(gè)名為Person的類型別名,并通過花括號(hào){}來定義了一個(gè)對(duì)象類型,其中有兩個(gè)屬性:name和age。然后使用Person類型別名來定義了一個(gè)person變量,它的類型為Person類型別名。
二、對(duì)象類型中的屬性修改器
1. 可選屬性
TypeScript中的可選屬性指的是,在定義對(duì)象類型時(shí),可以設(shè)置一些屬性為可選屬性,即不是必須存在的屬性。具體的語法是在屬性名稱后面加上一個(gè)問號(hào)(?
),如下所示:
interface Person {
name: string;
age?: number;
gender?: string;
}
在上面的例子中,age
和gender
是可選屬性。也就是說,在聲明一個(gè)Person
類型的對(duì)象時(shí),可以只包含name
屬性,而不必提供age
和gender
屬性。如果提供了這兩個(gè)屬性,它們的值必須符合對(duì)應(yīng)的類型定義。
下面分多個(gè)角度舉例說明可選屬性的用法和好處。
(1). 增強(qiáng)代碼的靈活性
使用可選屬性可以增強(qiáng)代碼的靈活性,使得我們?cè)诼暶鲗?duì)象的時(shí)候可以根據(jù)需要選擇性地添加屬性,而不是強(qiáng)制要求屬性必須存在。這樣一來,一些在某些場(chǎng)景下沒有用處的屬性就不必被強(qiáng)制賦值了,節(jié)約了代碼修改的時(shí)間和精力。
舉個(gè)例子,我們?cè)诙x一個(gè)Book
接口時(shí),可以將author
、publisher
和description
屬性都定義為可選屬性:
interface Book {
title: string;
author?: string;
publisher?: string;
description?: string;
}
然后在使用這個(gè)接口定義對(duì)象的時(shí)候,可以按照需求來添加這些屬性,比如:
const book1: Book = {
title: 'TypeScript in Action',
author: 'Erick Wendel'
};
const book2: Book = {
title: 'JavaScript: The Good Parts',
author: 'Douglas Crockford',
publisher: 'Yahoo Press'
};
const book3: Book = {
title: 'JavaScript: The Definitive Guide',
author: 'David Flanagan',
description: 'This book provides a complete description of the JavaScript language.'
};
在以上例子中,我們?cè)诼暶?code>book1時(shí)只提供了title
和author
屬性,因?yàn)樗鼈兪潜匦璧膶傩浴6诼暶?code>book2時(shí),我們?cè)黾恿?code>publisher屬性,因?yàn)檫@個(gè)屬性在這個(gè)場(chǎng)景下是有用的。在聲明book3
時(shí),我們只提供了title
和author
屬性,同時(shí)利用了description
屬性來描述這本書的內(nèi)容。所以,這樣的語法是非常方便的。
(2). 構(gòu)建可靠的對(duì)象類型檢查
使用可選屬性還能幫助我們構(gòu)建可靠的對(duì)象類型檢查。
在JavaScript中,我們會(huì)遇到無效的對(duì)象屬性,因?yàn)樗鼈儧]被正確地定義或被更新。這些錯(cuò)誤通常很難發(fā)現(xiàn),結(jié)果會(huì)導(dǎo)致代碼崩潰或是運(yùn)行出現(xiàn)錯(cuò)誤。
TypeScript可以用類型檢查來防止這種問題。通過定義對(duì)象屬性為可選屬性,我們可以預(yù)防掉對(duì)象屬性定義時(shí)的錯(cuò)誤,從而構(gòu)建可靠地類型檢查系統(tǒng)。如果屬性被定義成可選的,那么它可以沒有定義,而且也不會(huì)觸發(fā)錯(cuò)誤。這樣我們就可以更容易地處理這些異常情形,從而提高代碼的可靠性和維護(hù)性。
下面是一個(gè)例子展示了使用可選屬性來保證類型檢查的可靠性:
interface Car {
brand: string;
model: string;
year?: number;
}
function getCarInfo(car: Car): string {
return `Brand: ${car.brand}, Model: ${car.model}${car.year ? `, Year: ${car.year}` : ''}`;
}
const car1: Car = { brand: 'Tesla', model: 'Model S', year: 2018 };
const car2: Car = { brand: 'BMW', model: 'X5' };
const car3: Car = { brand: 'Mercedes', model: 'E220', year: '2021' };
console.log(getCarInfo(car1)); // Brand: Tesla, Model: Model S, Year: 2018
console.log(getCarInfo(car2)); // Brand: BMW, Model: X5
console.log(getCarInfo(car3)); // Brand: Mercedes, Model: E220
在上面的例子中,我們定義了一個(gè)Car
接口,并定義year
屬性為可選屬性。可以清晰地看到,我們?cè)?code>getCarInfo函數(shù)中使用了year
屬性的值來返回車的信息。當(dāng)year
屬性可選時(shí),我們?cè)讷@取year
屬性時(shí)需要先檢查它是否存在,否則輸出的字符串結(jié)果將不符合我們預(yù)期。在car3
的定義中,我們給year
屬性賦的值是一個(gè)字符串型而不是數(shù)字型,這時(shí)TypeScript會(huì)提示錯(cuò)誤。
(3). 提供默認(rèn)屬性值
除了類型檢查外,我們還可以用可選屬性來提供默認(rèn)屬性值。在某些場(chǎng)景下,如果對(duì)象的某些屬性沒有被定義,那么我們可以提供一個(gè)默認(rèn)值,以確保代碼可以正常運(yùn)行。
舉個(gè)例子,在定義一個(gè)Product
接口時(shí)可以使用可選屬性提供一個(gè)price
屬性的默認(rèn)值,如下所示:
interface Product {
name: string;
price?: number;
}
const shirt: Product = { name: 'Shirt' };
const pants: Product = { name: 'Pants', price: 45.00 };
console.log(shirt.price || 15.00); // 15
console.log(pants.price || 15.00); // 45
在上面的例子中,我們給shirt
對(duì)象定義了一個(gè)默認(rèn)的price
屬性值為15,在打印price
屬性時(shí),因?yàn)?code>shirt對(duì)象沒有定義price
屬性,所以輸出的值是默認(rèn)值15
。而在打印pants
的price
屬性時(shí),因?yàn)?code>pants對(duì)象定義了price
屬性,輸出的是45
,這是由于該屬性已定義的值是45。
2. 只讀屬性
TypeScript中,我們可以聲明一個(gè)對(duì)象類型中的屬性為只讀屬性,即該屬性的值一旦被賦值就不能再被修改。
舉例來說,假設(shè)有一個(gè)Student類型的對(duì)象,其中包含學(xué)生的姓名和年齡。我們可以將學(xué)生的姓名聲明為只讀屬性,代碼如下:
type Student = {
readonly name: string;
age: number;
}
在上述代碼中,我們使用了readonly關(guān)鍵字來將name屬性聲明為只讀屬性。這意味著一旦我們給該屬性賦值,就無法再修改它的值。
下面再舉一個(gè)例子,假設(shè)我們有一個(gè)Point類型的對(duì)象,包含了二維平面上的坐標(biāo)x和y。我們可以將該對(duì)象中的x和y屬性都聲明為只讀屬性,以保證對(duì)象的坐標(biāo)值不會(huì)被意外修改。代碼如下:
type Point = {
readonly x: number;
readonly y: number;
}
const p: Point = { x: 0, y: 0 };
// 錯(cuò)誤,無法修改只讀屬性
p.x = 10;
在上述代碼中,我們使用了readonly關(guān)鍵字將Point類型中的x和y屬性都聲明為只讀屬性。在給p對(duì)象中的x屬性賦值之后,我們?cè)噲D修改該屬性的值,但是因?yàn)樗侵蛔x屬性,所以會(huì)編譯錯(cuò)誤。
3. 索引簽名
在 TypeScript 中,對(duì)象類型可以包含索引簽名,以支持在動(dòng)態(tài)屬性上訪問屬性值。索引簽名允許您在對(duì)象類型中定義一個(gè)模式,該模式指定應(yīng)該具有哪些屬性和屬性類型。以下是一個(gè)示例:
interface ExampleObject {
[key: string]: string;
}
const exampleObject: ExampleObject = {
property1: "value1",
property2: "value2",
// ...
};
這里的索引簽名 [key: string]: string
意味著對(duì)象 ExampleObject
中的所有屬性的鍵都是字符串,所有屬性的值都是字符串。因此,可以使用類似于 exampleObject.property1
這樣的關(guān)鍵字為其屬性賦值或訪問屬性值。
下面是一些其他角度的示例:
- 在對(duì)象類型中使用數(shù)字索引簽名,以表示索引為數(shù)字的屬性:
interface ExampleObject {
[key: number]: string;
}
const exampleObject: ExampleObject = {
0: "value1",
1: "value2",
// ...
};
- 在對(duì)象類型中使用只讀索引簽名,以表示不希望在運(yùn)行時(shí)更改的屬性:
interface ExampleObject {
readonly [key: string]: string;
}
const exampleObject: ExampleObject = {
property1: "value1",
property2: "value2",
// ...
};
exampleObject.property1 = "new value"; // This will cause a TypeScript error
- 在對(duì)象類型中使用聯(lián)合類型索引簽名,以表示可以具有多個(gè)類型的屬性:
interface ExampleObject {
[key: string]: string | number;
}
const exampleObject: ExampleObject = {
property1: "value1",
property2: 2,
// ...
};
在這個(gè)示例中,屬性的值可以是字符串或數(shù)字。
4. 擴(kuò)展類型
TypeScript中的對(duì)象類型是通過接口來定義的,接口可以擴(kuò)展其他接口,從而實(shí)現(xiàn)對(duì)象類型的擴(kuò)展。
例如,我們可以定義一個(gè)基礎(chǔ)的對(duì)象類型接口Person,然后定義一個(gè)Student接口來繼承Person接口并添加一些額外的屬性:
interface Person {
name: string;
age: number;
}
interface Student extends Person {
school: string;
grade: string;
}
這樣,Student接口就包含了Person接口中所有的屬性,同時(shí)添加了school和grade屬性。
5. 交叉類型
交叉類型(Intersection Types)是Typescript中的一種類型操作符,用于將多個(gè)類型合并成一個(gè)類型。它的語法是將多個(gè)類型通過 & 連接起來,例如:
type Person = {
name: string;
age: number;
};
type Employee = {
employer: string;
salary: number;
};
type Worker = Person & Employee;
在上面的例子中,我們定義了兩個(gè)類型Person和Employee,并將它們通過 & 連接起來得到了一個(gè)新的類型Worker。這個(gè)新類型包含了兩個(gè)原類型中的所有屬性。
與交叉類型類似的還有聯(lián)合類型(Union Types),用于將多個(gè)類型中的一個(gè)合并成一個(gè)類型,并采用 | 連接。
交叉類型和interface的extends擴(kuò)展類型的區(qū)別
與交叉類型相比,使用interface的extends擴(kuò)展類型可以實(shí)現(xiàn)類似的效果,但是它們的設(shè)計(jì)思想不同。extends用于在一個(gè)類型基礎(chǔ)上擴(kuò)展屬性和方法,而交叉類型則是將多個(gè)類型合并起來以創(chuàng)建一個(gè)新的類型。
例如,我們定義了一個(gè)接口Animal:
interface Animal {
name: string;
eat(): void;
}
然后定義了兩個(gè)接口Dog和Person,并通過extends方式擴(kuò)展了它們的屬性和方法:
interface Dog extends Animal {
bark(): void;
}
interface Person extends Animal {
age: number;
speak(): void;
}
上面代碼中,Dog和Person都擴(kuò)展了Animal接口,即它們都繼承了Animal中的name屬性和eat方法。與交叉類型不同的是,Dog和Person無法同時(shí)擁有Animal以外的屬性和方法。
綜上所述,交叉類型和extends擴(kuò)展類型雖然都用于繼承和合并類型,但是它們的應(yīng)用場(chǎng)景和用途不同。交叉類型
適合于將多個(gè)類型合并為一個(gè)類型,而extends擴(kuò)展類型
適合于在一個(gè)類型基礎(chǔ)上擴(kuò)展屬性和方法。在不同的場(chǎng)景中,我們可以選擇不同的方式來定義和組合類型。
6. 泛型對(duì)象類型
泛型對(duì)象類型可以用于對(duì)象屬性中的類型聲明。例如,以下代碼定義了一個(gè)對(duì)象類型,該對(duì)象具有不同類型的屬性:
interface List<T> {
data: T[]
add: (item: T) => void
}
const list1: List<string> = {
data: ['hello', 'world'],
add(item) {
this.data.push(item)
}
}
const list2: List<number> = {
data: [1, 2],
add(item) {
this.data.push(item)
}
}
在上面的代碼中,<T>
表示泛型對(duì)象類型,我們?cè)?code>List<T>中使用了該類型,以聲明data
屬性和add
方法的參數(shù)和返回類型。
原文鏈接:https://blog.csdn.net/jieyucx/article/details/131347619
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2023-09-18 Echarts常見問題總結(jié)(持續(xù)更新)
- 2022-09-01 ASP.NET?Core通用主機(jī)的系統(tǒng)配置_實(shí)用技巧
- 2022-06-29 Android實(shí)用小技巧之利用Lifecycle寫出更好維護(hù)的代碼_Android
- 2023-09-12 利用ImportBeanDefinitionRegistrar手動(dòng)向Spring容器注入Bean
- 2022-05-19 nginx中封禁ip和允許內(nèi)網(wǎng)ip訪問的實(shí)現(xiàn)示例_nginx
- 2022-07-14 Python中添加搜索路徑的方法實(shí)例_python
- 2024-01-16 URLClassLoader詳解
- 2024-03-22 【IDEA】maven項(xiàng)目刷新依賴的兩種方式
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支