日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

TypeScript中的對(duì)象類型(可選屬性 只讀屬性 交叉類型)

作者:jieyucx 更新時(shí)間: 2023-07-26 編程語言

一、定義對(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;
}

在上面的例子中,agegender是可選屬性。也就是說,在聲明一個(gè)Person類型的對(duì)象時(shí),可以只包含name屬性,而不必提供agegender屬性。如果提供了這兩個(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í),可以將authorpublisherdescription屬性都定義為可選屬性:

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í)只提供了titleauthor屬性,因?yàn)樗鼈兪潜匦璧膶傩浴6诼暶?code>book2時(shí),我們?cè)黾恿?code>publisher屬性,因?yàn)檫@個(gè)屬性在這個(gè)場(chǎng)景下是有用的。在聲明book3時(shí),我們只提供了titleauthor屬性,同時(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。而在打印pantsprice屬性時(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)鍵字為其屬性賦值或訪問屬性值。

下面是一些其他角度的示例:

  1. 在對(duì)象類型中使用數(shù)字索引簽名,以表示索引為數(shù)字的屬性:
interface ExampleObject {
  [key: number]: string;
}

const exampleObject: ExampleObject = {
  0: "value1",
  1: "value2",
  // ...
};
  1. 在對(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
  1. 在對(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

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新