溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

TypeScript是什么意思

發(fā)布時(shí)間:2021-12-16 10:27:31 來源:億速云 閱讀:140 作者:小新 欄目:大數(shù)據(jù)

這篇文章主要為大家展示了“TypeScript是什么意思”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“TypeScript是什么意思”這篇文章吧。

TypeScript 為數(shù)據(jù)類型

TypeScript 并沒有很多可用于聲明變量的內(nèi)置數(shù)據(jù)類型,只有字符串、數(shù)字和布爾。這三種類型都是 any 類型(any 類型在聲明變量時(shí)也可以使用)的子類型。您可以針對 null 或未定義的類型來設(shè)置或測試通過這四種類型聲明的變量。您還可以將這些方法聲明為 void,來指明他們未返回值。

此示例將一個(gè)變量聲明為字符串:

var name: string;

您可以使用枚舉值和四種對象類型來擴(kuò)展此簡單類型系統(tǒng):接口、類、數(shù)組和函數(shù)。例如,以下代碼使用名稱 ICustomerShort 定義了一個(gè)接口(一種對象類型)。該接口包含兩個(gè)成員:屬性 Id 和方法 CalculateDiscount:

interface ICustomerShort
{
  Id: number;
  CalculateDiscount(): number;
}

正如在 C# 中一樣,在聲明變量時(shí),您可以使用接口并返回類型。此示例將變量 cs 聲明為類型 ICustomerShort:

var cs: ICustomerShort;

您還可以將對象類型定義為類,類不同于接口,可以包含可執(zhí)行代碼。此示例使用一個(gè)屬性和一個(gè)方法定義了 CustomerShort 類:

class CustomerShort
{
  FullName: string;
  UpdateStatus( status: string ): string
  {
    ...manipulate status... 
    return status;
  }
}

類似于 C# 的較新版本,在定義屬性時(shí),不需要提供實(shí)現(xiàn)代碼。此名稱和類型的簡單聲明就足夠了。類可以實(shí)現(xiàn)一個(gè)或多個(gè)接口,如圖 1 中所示,通過其屬性將我的 ICustomerShort 接口添加到我的 CustomerShort 類。

圖 1 將接口添加到類

class CustomerShort implements ICustomerShort
{
  Id: number;
  FullName: string;
  UpdateStatus(status: string): string
  {
    ...manipulate status...
    return status;
  }
  CalculateDiscount(): number
  {
    var discAmount: number;
    ...calculate discAmount...
    return discAmount;
  }
}

圖 1 所示,在 TypeScript 中實(shí)現(xiàn)接口的語法與在 C# 中的實(shí)現(xiàn)一樣簡單。要實(shí)現(xiàn)此接口的成員,您只需添加帶有相同名稱的成員,而無需將接口名稱綁定到相關(guān)類成員。在此示例中,我只將 Id 和 CalculateDiscount 添加到了類以實(shí)現(xiàn) ICustomerShort。TypeScript 還允許您使用對象類型文字。此代碼將變量 cst 設(shè)置為包含一個(gè)屬性和一個(gè)方法的對象文字:

var csl = {
            Age: 61,
            HaveBirthday(): number
          {
            return this.Age++;
          }
        };

此示例使用對象類型指定 UpdateStatus 方法的返回值:

UpdateStatus( status: string ): { 
  status: string; valid: boolean }
{
  return {status: "New",
          valid: true
         };
}

除了對象類型(類、接口、文字和數(shù)組)之外,您還可以定義描述函數(shù)簽名的函數(shù)類型。以下代碼對我的 CustomerShort 類的 CalculateDiscount 進(jìn)行重寫以接受名為 discountAmount 的單個(gè)參數(shù):

interface ICustomerShort
{
  Id: number;
  CalculateDiscount( discountAmount:
    ( discountClass: string, 
      multipleDiscount: boolean ) => number): number
}

使用接受兩個(gè)參數(shù)(一個(gè)字符串參數(shù)、一個(gè)布爾參數(shù))的函數(shù)類型對該參數(shù)進(jìn)行定義,并返回一個(gè)數(shù)字。如果您是 C# 開發(fā)人員,您可能會發(fā)現(xiàn)此語法看上去像是 lambda 表達(dá)式。

實(shí)現(xiàn)此接口的類如圖 2 所示。

圖 2 此類實(shí)現(xiàn)適當(dāng)?shù)慕涌?/strong>

class CustomerShort implements ICustomerShort
{
  Id: number;
  FullName: string;
  CalculateDiscount( discountedAmount:
    ( discountClass: string, 
      multipleDiscounts: boolean ) => number ): number
  {
    var discAmount: number;
    ...calculate discAmount...
    return discAmount;
  }
}

類似于 C# 的較新版本,TypeScript 還可以從初始化變量的值,推斷出此變量的數(shù)據(jù)類型。在此示例中,TypeScript 假設(shè)變量 myCust 為 CustomerShort:

var myCust= new CustomerShort();
myCust.FullName = "Peter Vogel";

類似于 C#,您可以使用接口來聲明變量,然后將此變量設(shè)置為實(shí)現(xiàn)此接口的對象:

var cs: ICustomerShort;
cs = new CustomerShort();
cs.Id = 11;
cs.FullName = "Peter Vogel";

最后,您還可以使用類型參數(shù)(看起來很像 C# 中的泛型)來使調(diào)用代碼指定要使用的數(shù)據(jù)類型。此示例允許創(chuàng)建類的代碼設(shè)置 Id 屬性的數(shù)據(jù)類型:

class CustomerTyped<T>
{
  Id: T;
}

此代碼先將 Id 屬性的數(shù)據(jù)類型設(shè)置為字符串,然后才使用它:

var cst: CustomerTyped<string>;
cst = new CustomerTyped<string>();
cst.Id = "A123";

要隔離類、接口和其他公共成員并避免名稱沖突,您可以在與 C# 命名空間類似的模塊中聲明這些構(gòu)造。您必須使用導(dǎo)出關(guān)鍵字標(biāo)記這些您希望提供給其他模塊使用的項(xiàng)。圖 3 中的模塊導(dǎo)出兩個(gè)接口和一個(gè)類。

圖 3 導(dǎo)出兩個(gè)接口和一個(gè)類

module TypeScriptSample
{
  export interface ICustomerDTO
  {
    Id: number;
  }
  export interface ICustomerShort extends ICustomerDTO
  {
    FullName: string;
  }
  export class CustomerShort implements ICustomerShort
  {
    Id: number;
    FullName: string;
  }

要使用導(dǎo)出的組件,您可以使用模塊名稱作為此組件名稱的前綴,如以下示例中所示:

var cs: TypeScriptSample.CustomerShort;

或者,您可以使用 TypeScript 導(dǎo)入關(guān)鍵字來建立此模塊的快捷方式:

import tss = TypeScriptSample;
...
var cs:tss.CustomerShort;

TypeScript 在數(shù)據(jù)類型化方面非常靈活

如果您是 C# 程序員,除了可能的變量聲明反轉(zhuǎn)(變量名稱在前,數(shù)據(jù)類型在后)和對象文字之外,您對這一切應(yīng)該非常熟悉。然而,TypeScript 中幾乎所有數(shù)據(jù)類型化都是可選的。此規(guī)范將數(shù)據(jù)類型描述為“注釋”。如果您省略數(shù)據(jù)類型(并且 TypeScript 無法推斷出此數(shù)據(jù)類型),則數(shù)據(jù)類型默認(rèn)為 any 類型。

TypeScript 也不要求數(shù)據(jù)類型嚴(yán)格匹配。TypeScript 使用規(guī)范稱為“結(jié)構(gòu)子類型化”的功能來確定兼容性。這與通常稱為“鴨子類型化”的功能類似。在 TypeScript 中,如果兩個(gè)類擁有具有相同類型的成員,就將他們視為相同。例如,以下是一個(gè)實(shí)現(xiàn) ICustomerShort 接口的 Customer&shy;Short 類:

interface ICustomerShort
{
  Id: number;
  FullName: string;
}
class CustomerShort implements ICustomerShort
{
  Id: number;
  FullName: string;
}

以下是一個(gè)與我的 CustomerShort 類相似的 CustomerDeviant 類:

class CustomerDeviant
{
  Id: number;
  FullName: string;
}

借助結(jié)構(gòu)子類型化,我可以使用帶有使用我的 CustomerShort 類或 ICustomerShort 接口定義的變量的 CustomerDevient。這些示例將 CustomerDeviant 與聲明為 CustomerShort 或 ICustomerShort 的變量互換使用:

var cs: CustomerShort;
cs = new CustomerDeviant
cs.Id = 11;
var csi: ICustomerShort;
csi = new CustomerDeviant
csi.FullName = "Peter Vogel";

這種靈活性使您可以將 TypeScript 對象文字分配給聲明為類或接口的變量,假設(shè)它們在結(jié)構(gòu)上兼容,如以下示例所示:

var cs: CustomerShort;
cs = {Id: 2,
      FullName: "Peter Vogel"
     }
var csi: ICustomerShort;
csi = {Id: 2,
       FullName: "Peter Vogel"
      }

這會引入導(dǎo)致可分配性常見問題的有關(guān)明顯類型、父類型和子類型的 TypeScript 特定功能,本文將跳過這部分內(nèi)容。例如,這些功能將允許 CustomerDeviant 擁有 CustomerShort 中不存在的成員,而不會導(dǎo)致我的示例代碼失敗。

TypeScript 擁有類

TypeScript 規(guī)范將此語言稱作實(shí)現(xiàn)“在面向?qū)ο蟮睦^承機(jī)制上[使用]原型鏈來實(shí)現(xiàn)許多變體的類模式”。實(shí)際上,這意味著 TypeScript 不只是數(shù)據(jù)類型化,而是高效地面向?qū)ο蟮摹?/p>

與 C# 接口可以從基接口進(jìn)行繼承一樣,TypeScript 接口也可以采用相同的方式擴(kuò)展另一個(gè)接口,即使另一個(gè)接口是在其他模塊中定義的。此示例擴(kuò)展了 ICustomerShort 接口并創(chuàng)建了名為 ICustomerLong 的新接口:

interface ICustomerShort
{
  Id: number;
}
interface ICustomerLong extends ICustomerShort
{
  FullName: string;
}

ICustomerLong 接口將擁有兩個(gè)成員:FullName 和 Id。在合并的接口中,先顯示來自此接口的成員。因此,我的 ICustomerLong 接口相當(dāng)于此接口:

interface ICustomerLongPseudo
{
  FullName: string;
  Id: number;
}

實(shí)現(xiàn) ICustomerLong 的類將需要這兩個(gè)屬性:

class CustomerLong implements ICustomerLong
{
  Id: number;
  FullName: string;
}

類可以用接口擴(kuò)展另一個(gè)接口的方式來擴(kuò)展其他類。圖 4 中的類擴(kuò)展了 CustomerShort,并將新屬性添加到定義中。它使用顯式 getter 和 setter 來定義屬性(盡管這不是一個(gè)特別有用的方法)。

圖 4 使用 getter 和 setter 定義的屬性

class CustomerShort
{
  Id: number;
}
class CustomerLong extends CustomerLong
{
  private id: number;
  private fullName: string;
  get Id(): number
  {
    return this.id
  }
  set Id( value: number )
  {
    this.id = value;
  }
  get FullName(): string
  {
    return this.fullName;
  }
  set FullName( value: string )
  {
    this.fullName = value;
  }
}

TypeScript 采用通過引用此類 (this) 訪問內(nèi)部字段(如 id 和 fullName)的最佳做法。這些類還可以具有包含 C# 剛采用的功能的構(gòu)造函數(shù):自動(dòng)定義字段。TypeScript 類中的構(gòu)造函數(shù)必須命名為構(gòu)造函數(shù),其公共參數(shù)會自動(dòng)定義為屬性,并從傳遞給這些屬性的值進(jìn)行初始化。在此示例中,構(gòu)造函數(shù)將接受字符串類型的名為 Company 的單個(gè)參數(shù):

export class CustomerShort implements ICustomerShort
{
  constructor(public Company: string)
  {       }

由于 Company 參數(shù)定義為公共,此類還獲取一個(gè)從傳遞給構(gòu)造函數(shù)的值初始化而來的名為 Company 的公共屬性。借助該功能,變量 comp 將設(shè)置為“PH&VIS”,如該示例所示:

var css: CustomerShort;
css = new CustomerShort( "PH&VIS" );
var comp = css.Company;

將構(gòu)造函數(shù)的參數(shù)聲明為私有會創(chuàng)建一個(gè)內(nèi)部屬性,此內(nèi)部屬性只能通過關(guān)鍵字 this 從類成員內(nèi)部的代碼進(jìn)行訪問。如果此參數(shù)沒有聲明為公共或私有,則不會生成屬性。

您的類必須擁有一個(gè)構(gòu)造函數(shù)。正如在 C# 中一樣,如果您未提供一個(gè)構(gòu)造函數(shù),系統(tǒng)將向您提供一個(gè)。如果您的類擴(kuò)展了其他類,則您創(chuàng)建的任何構(gòu)造函數(shù)必須包含對 super 的調(diào)用。將調(diào)用正在擴(kuò)展的類上的構(gòu)造函數(shù)。此示例包括帶有 super 調(diào)用的構(gòu)造函數(shù),該調(diào)用向基類的構(gòu)造函數(shù)提供參數(shù):

class MyBaseClass
{
  constructor(public x: number, public y: number ) { }   
}
class MyDerivedClass extends MyBaseClass
{
  constructor()
  {
    super(2,1);
  }
}

TypeScript 以不同的方式繼承

同樣,如果您是 C# 程序員,除了一些有趣的關(guān)鍵字 (extends) 之外,您對這一切都會感到熟悉。但是同樣,擴(kuò)展類或接口與 C# 中的繼承機(jī)制并不完全相同。TypeScript 規(guī)范針對被擴(kuò)展的類(“基類”)和擴(kuò)展它的類(“派生類”)使用常規(guī)術(shù)語。但是,例如,此規(guī)范將一個(gè)類稱為“遺產(chǎn)規(guī)范”,而沒有使用單詞“繼承”。

首先,在定義基類時(shí),TypeScript 的選項(xiàng)要少于 C# 的選項(xiàng)。您無法將類或成員聲明為不能替代的、抽象的或虛擬的(盡管接口提供了很多虛擬基類所提供的功能)。

無法防止一些成員不能被繼承。派生類繼承基類的所有成員,包括公共和私有成員(基類的所有公共成員都可替代,而私有成員都不可替代)。要替代公共成員,只需在派生類中使用相同簽名定義一個(gè)成員。雖然您可以使用 super 關(guān)鍵字來從派生類訪問公共方法,但無法使用 super 訪問基類中的屬性(盡管您可以替代此屬性)。

TypeScript 允許您通過簡單地使用相同名稱和新成員聲明接口來增加一個(gè)接口。這允許您擴(kuò)展現(xiàn)有 JavaScript 代碼,而無需創(chuàng)建新的命名類型。圖 5 中的示例通過兩個(gè)單獨(dú)的接口定義來定義 ICustomerMerge 接口,然后在類中實(shí)現(xiàn)該接口。

圖 5 通過兩個(gè)接口定義來定義的 ICustomerMerge 接口

interface ICustomerMerge
{
  MiddleName: string;
}
interface ICustomerMerge
{
  Id: number;
}
class CustomerMerge implements ICustomerMerge
{
  Id: number;
  MiddleName: string;
}

這些類還可以擴(kuò)展其他類,但不能擴(kuò)展接口。在 TypeScript 中,接口也可以擴(kuò)展類,但只能以涉及繼承的方式實(shí)現(xiàn)。當(dāng)接口擴(kuò)展類時(shí),接口包括所有類成員(公共和私有),但不包括此類的實(shí)現(xiàn)。在圖 6 中,ICustomer 接口將擁有私有成員 id、公共成員 Id 以及公共成員 MiddleName。

圖 6 帶有所有成員的擴(kuò)展類

class Customer
{
  private id: number;
  get Id(): number
  {
    return this.id
  }
  set Id( value: number )
  {
    this.id = value;
  }
}
interface ICustomer extends Customer
{
  MiddleName: string;
}

ICustomer 接口具有很大的限制,您只能將其與擴(kuò)展該接口所擴(kuò)展的類(在本示例中,為 Customer 類)的類結(jié)合使用。TypeScript 需要您在要從此接口擴(kuò)展的類上繼承的接口中(而不是在派生類中重新實(shí)現(xiàn)的接口上)包括私有成員。例如,使用 ICustomer 接口的新類需要為 MiddleName 提供一個(gè)實(shí)現(xiàn)(因?yàn)?MiddleName 只在此接口中指定)。使用 ICustomer 的開發(fā)人員可以選擇從 Customer 類繼承或替代公共方法,但無法替代私有 id 成員。

此示例展示了根據(jù)需要實(shí)現(xiàn) ICustomer 接口并擴(kuò)展 Customer 類的類(稱為 NewCustomer)。在本示例中,NewCustomer 從 Customer 繼承 Id 的實(shí)現(xiàn),并為 MiddleName 提供一個(gè)實(shí)現(xiàn):

class NewCustomer extends Customer implements ICustomer
{
  MiddleName: string;
}

這一接口、類、實(shí)現(xiàn)和擴(kuò)展的組合為您進(jìn)行定義用于擴(kuò)展在其他對象模型中定義的類的類提供了一種受控的方式(有關(guān)詳細(xì)信息,請查看語言規(guī)范 7.3 部分,“擴(kuò)展類的接口”)。再加上 TypeScript 使用其他 JavaScript 庫相關(guān)信息的能力,TypeScript 可以讓您編寫與在那些庫中定義的對象配合使用的 TypeScript 代碼。

TypeScript 了解您的庫

除了了解在您的應(yīng)用程序中定義的類和接口,您可以向 TypeScript 提供有關(guān)其他對象庫的信息??梢酝ㄟ^ TypeScript 聲明關(guān)鍵字進(jìn)行處理。這就創(chuàng)建了規(guī)范所指的“環(huán)境聲明”。您可能從來不需要親自使用聲明關(guān)鍵字,因?yàn)槟梢栽?DefinitelyTyped 站點(diǎn) (definitelytyped.org) 上找到大多數(shù) JavaScript 庫的定義文件。通過這些定義文件,TypeScript 可以高效地“閱讀有關(guān)您需使用的庫的文檔”。

當(dāng)然,在使用構(gòu)成該庫的對象時(shí),“閱讀文檔”意味著您將獲取數(shù)據(jù)類型化的 IntelliSense 支持和編譯時(shí)檢查。在某些情況下,這還允許 TypeScript 從使用變量的上下文中推斷出變量的類型。借助于隨 TypeScript 提供的 lib.d.ts 定義文件,TypeScript 假設(shè)在以下代碼中變量定位標(biāo)記的類型為 HTMLAnchorElement:

var anchor = document.createElement( "a" );

當(dāng) createElement 方法傳遞字符串“a”時(shí),此定義文件指定這就是由此方法所返回的結(jié)果。例如,知道定位標(biāo)記是 HTMLAnchorElement,意味著 TypeScript 知道定位標(biāo)記變量將支持 addEventListener 方法。

TypeScript 數(shù)據(jù)類型接口還適用于參數(shù)類型。例如,addEventListener 方法接受兩個(gè)參數(shù)。第二個(gè)為函數(shù),addEventListener 在其中傳遞了類型 PointerEvent 的對象。TypeScript 知道這一點(diǎn),并支持訪問此函數(shù)中 PointerEvent 類的 cancelBubble 屬性:

span.addEventListener("pointerenter", function ( e )
{
  e.cancelBubble = true;
}

其他 JavaScript 的定義文件以 lib.d.ts 提供 HTML DOM 相關(guān)信息的方式提供類似的功能。例如,在將 backbone.d.ts 文件添加到我的項(xiàng)目之后,我可以聲明一個(gè)類,該類擴(kuò)展了 Backbone Model 類并通過如下代碼實(shí)現(xiàn)了我的接口:

class CustomerShort extends bb.Model implements ICustomerShort
{
}

如果您對如何將 TypeScript 與 Backbone、Knockout 結(jié)合使用的詳細(xì)信息感興趣,請查閱我的實(shí)用 TypeScript 專欄 (bit.ly/1BRh8NJ)。在新的一年中,我將詳細(xì)研究如何將 TypeScript 與 Angular 結(jié)合使用。

TypeScript 的功能遠(yuǎn)不止此。TypeScript 版本 1.3 將來必定包括 union 數(shù)據(jù)類型(例如,以便支持返回特定類型列表的函數(shù))和聚合。TypeScript 團(tuán)隊(duì)正在與將數(shù)據(jù)類型化應(yīng)用于 JavaScript(Flow 和 Angular)的其他團(tuán)隊(duì)合作,以確保 TypeScript 可以與盡可能多的 JavaScript 庫結(jié)合使用。

如果您需要執(zhí)行 JavaScript 支持而 TypeScript 不允許的操作,則可以始終集成您的 JavaScript 代碼,因?yàn)?TypeScript 是 JavaScript 的超集。

以上是“TypeScript是什么意思”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI