最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TypeScript聲明合并的多種使用方式

 更新時(shí)間:2026年05月12日 09:42:38   作者:吳聲子夜歌  
本文主要介紹了TypeScript聲明合并的多種使用方式,包括接口聲明合并、枚舉聲明合并、類聲明合并、命名空間聲明合并、模塊擴(kuò)充聲明和全局聲明擴(kuò)充,感興趣的可以了解一下

聲明是編程語(yǔ)言中的基礎(chǔ)結(jié)構(gòu),它描述了一個(gè)標(biāo)識(shí)符所表示的含義。在TypeScript語(yǔ)言中,一個(gè)標(biāo)識(shí)符總共可以有以下三種含義:

  • 表示一個(gè)值。
  • 表示一個(gè)類型。
  • 表示一個(gè)命名空間。

下例中,我們分別定義了值、類型和命名空間。其中,常量zero屬于值,接口Point屬于類型,而命名空間Utils則屬于命名空間。示例如下:

const zero = 0;

interface Point {
    x: number;
    y: number;
}

namespace Utils {}

對(duì)于同一個(gè)標(biāo)識(shí)符而言,它可以同時(shí)具有上述多種含義。例如,有一個(gè)標(biāo)識(shí)符A,它可以同時(shí)表示一個(gè)值、一種類型和一個(gè)命名空間。示例如下:

const A = 0;

interface A {}

namespace A {}

在同一聲明空間內(nèi)使用的標(biāo)識(shí)符必須唯一。TypeScript語(yǔ)言中的大部分語(yǔ)法結(jié)構(gòu)都能夠創(chuàng)建出新的聲明空間,例如函數(shù)聲明和類聲明都能夠創(chuàng)建出一個(gè)新的聲明空間。最典型的聲明空間是全局聲明空間和模塊聲明空間。當(dāng)編譯器發(fā)現(xiàn)同一聲明空間內(nèi)存在同名的聲明時(shí),會(huì)嘗試將所有同名的聲明合并為一個(gè)聲明,即聲明合并;若發(fā)現(xiàn)無(wú)法進(jìn)行聲明合并,則會(huì)產(chǎn)生編譯錯(cuò)誤。聲明合并是TypeScript語(yǔ)言特有的行為。在進(jìn)行聲明合并時(shí),編譯器會(huì)按照標(biāo)識(shí)符的含義進(jìn)行分組合并,即值和值合并、類型和類型合并以及命名空間和命名空間合并。但是并非所有同名的聲明都允許進(jìn)行聲明合并,例如,常量聲明a和函數(shù)聲明a之間不會(huì)進(jìn)行聲明合并。

接下來(lái),將具體介紹TypeScript語(yǔ)言中的聲明合并,包括接口聲明、枚舉聲明、類聲明、命名空間聲明、擴(kuò)充模塊聲明、擴(kuò)充全局聲明。

1、接口聲明合并

接口聲明為標(biāo)識(shí)符定義了類型含義。在同一聲明空間內(nèi)聲明的多個(gè)同名接口會(huì)合并成一個(gè)接口聲明。下例中,存在兩個(gè)A接口聲明,它們屬于同一聲明空間。編譯器會(huì)將兩個(gè)A接口聲明中的類型成員合并到一起,合并后的接口A等同于接口MergedA。示例如下:

interface A {
    a: string;
}

interface A {
    b: number;
}

interface MergedA {
    a: string;
    b: number;
}

若待合并的接口中存在同名的屬性簽名類型成員,那么這些同名的屬性簽名必須是相同的類型,否則會(huì)因?yàn)楹喜_突而產(chǎn)生編譯錯(cuò)誤。例如,在下例的兩個(gè)接口A中,屬性成員a的類型分別為number類型和string類型,在合并接口時(shí)會(huì)發(fā)生沖突。示例如下:

interface A {
    a: number;
}

interface A {
    a: string; // 編譯錯(cuò)誤
}

若待合并的接口中存在同名的方法簽名類型成員,那么同名的方法簽名類型成員會(huì)被視為函數(shù)重載,并且靠后定義的方法簽名具有更高的優(yōu)先級(jí)。例如,下例的兩個(gè)A接口聲明中都定義了方法簽名類型成員f。在合并后的接口A中,方法簽名f具有兩個(gè)重載簽名并且后聲明的f方法(第6行)具有更高的優(yōu)先級(jí)。示例如下:

interface A {
    f(x: any): void;
}

interface A {
    f(x: string): boolean;
}

interface MergedA {
    f(x: string): boolean;
    f(x: any): void;
}

合并重載簽名的基本原則是后聲明的重載簽名具有更高優(yōu)先級(jí)。但也存在一個(gè)例外,若重載簽名的參數(shù)類型中包含字面量類型,則該重載簽名具有更高的優(yōu)先級(jí)。例如,下例中盡管第2行的方法簽名f是先聲明的,但在接口合并后仍具有更高的優(yōu)先級(jí),因?yàn)樗暮瘮?shù)簽名中帶有字面量類型。示例如下:

interface A {
    f(x: 'foo'): boolean;
}

interface A {
    f(x: any): void;
}

interface MergedA {
    f(x: 'foo'): boolean;
    f(x: any): void;
}

若待合并的接口中存在多個(gè)調(diào)用簽名類型成員或構(gòu)造簽名類型成員,那么它們將被視作函數(shù)重載和構(gòu)造函數(shù)重載。與合并方法簽名類型成員相同,后聲明的調(diào)用簽名類型成員和構(gòu)造簽名類型成員具有更高的優(yōu)先級(jí),同時(shí)也會(huì)參考參數(shù)類型中是否包含字面量類型。示例如下:

interface A {
    new (x: any): object;
    (x: any): any;
}

interface A {
    new (x: string): Date;
    (x: string): string;
}

interface MergedA {
    new (x: string): Date;
    new (x: any): object;
    (x: string): string;
    (x: any): any;
}

當(dāng)涉及重載時(shí),接口合并的順序變得尤為重要,因?yàn)樗鼘⒂绊懼剌d的解析順序。

若待合并的接口中存在多個(gè)字符串索引簽名或數(shù)值索引簽名,則將產(chǎn)生編譯錯(cuò)誤。在合并接口時(shí),所有的接口中只允許存在一個(gè)字符串索引簽名和一個(gè)數(shù)值索引簽名。示例如下:

interface A {
    [prop: string]: string;
}

interface A {
    [prop: number]: string;
}

interface MergedA {
    [prop: string]: string;
    [prop: number]: string;
}

若待合并的接口是泛型接口,那么所有同名接口必須有完全相同的類型參數(shù)列表。若待合并的接口存在繼承的接口,那么所有繼承的接口會(huì)被合并為單一的父接口。在實(shí)際程序中,我們應(yīng)避免復(fù)雜接口的合并行為,因?yàn)檫@會(huì)讓代碼變得難以理解。

2、枚舉聲明合并

多個(gè)同名的枚舉聲明會(huì)合并成一個(gè)枚舉聲明。在合并枚舉聲明時(shí),只允許其中一個(gè)枚舉聲明的首個(gè)枚舉成員省略初始值。示例如下:

enum E {
    A,
}

enum E {
    B = 1,
}

enum E {
    C = 2,
}

let e: E;
e = E.A;
e = E.B;
e = E.C;

此例中,第2行的首個(gè)枚舉成員省略了初始值,因此TypeScript會(huì)自動(dòng)計(jì)算初始值。第6行和第10行,必須為首個(gè)枚舉成員定義初始值,否則將產(chǎn)生編譯錯(cuò)誤,因?yàn)榫幾g器無(wú)法在多個(gè)同名枚舉聲明之間自動(dòng)地計(jì)算枚舉值。

枚舉聲明合并的另外一點(diǎn)限制是,多個(gè)同名的枚舉聲明必須同時(shí)為const枚舉或非const枚舉,不允許混合使用。示例如下:

// 正確
enum E0 {
    A,
}
enum E0 {
    B = 1,
}

// 正確
const enum E1 {
    A,
}
const enum E1 {
    B = 1,
}

// 編譯錯(cuò)誤
enum E2 {
    A,
}
const enum E2 {
    B = 1,
}

3、類聲明合并

TypeScript不支持合并同名的類聲明,但是外部類聲明可以與接口聲明進(jìn)行合并,合并后的類型為類類型。示例如下:

declare class C {
    x: string;
}

interface C {
    y: number;
}

let c: C = new C();
c.x;
c.y;

4、命名空間聲明合并

命名空間的聲明合并會(huì)稍微復(fù)雜一些,它可以與命名空間、函數(shù)、類和枚舉進(jìn)行合并。

4.1 命名空間與命名空間合并

與合并接口類似,同名的命名空間也會(huì)進(jìn)行合并。例如,編譯器會(huì)將下例中的兩個(gè)Animals命名空間進(jìn)行合并,合并后的命名空間等同于命名空間MergedAnimals。示例如下:

namespace Animals {
    export class Bird {}
}

namespace Animals {
    export interface CanFly {
        canFly: boolean;
    }
    export class Dog {}
}

namespace MergedAnimals {
    export interface CanFly {
        canFly: boolean;
    }
    export class Bird {}
    export class Dog {}
}

如果存在嵌套的命名空間,那么在合并外層命名空間時(shí),同名的內(nèi)層命名空間也會(huì)進(jìn)行合并。示例如下:

namespace outer {
    export namespace inner {
        export var x = 10;
    }
}
namespace outer {
    export namespace inner {
        export var y = 20;
    }
}

namespace MergedOuter {
    export namespace inner {
        export var x = 10;
        export var y = 20;
    }
}

在合并命名空間聲明時(shí),命名空間中的非導(dǎo)出成員不會(huì)被合并,它們只能在各自的命名空間中使用。示例如下:

namespace NS {
    const a = 0;

    export function foo() {
        a;  // 正確
    }
}

namespace NS {
    export function bar() {
        foo(); // 正確

        a;  // 編譯錯(cuò)誤:找不到 'a'
    }
}

4.2 命名空間與函數(shù)合并

同名的命名空間聲明與函數(shù)聲明可以進(jìn)行合并,但是要求函數(shù)聲明必須位于命名空間聲明之前,這樣做能夠確保先創(chuàng)建出一個(gè)函數(shù)對(duì)象。函數(shù)與命名空間合并就相當(dāng)于給函數(shù)對(duì)象添加額外的屬性。示例如下:

function f() {
    return f.version;
}

namespace f {
    export const version = '1.0';
}

f();   // '1.0'
f.version; // '1.0'

4.3 命名空間與類合并

同名的命名空間聲明與類聲明可以進(jìn)行合并,但是要求類聲明必須位于命名空間聲明之前,這樣做能夠確保先創(chuàng)建出一個(gè)構(gòu)造函數(shù)對(duì)象。命名空間與類的合并提供了一種創(chuàng)建內(nèi)部類的方式。示例如下:

class Outer {
    inner: Outer.Inner = new Outer.Inner();
}

namespace Outer {
    export class Inner {}
}

我們也可以利用命名空間與類的聲明合并來(lái)為類添加靜態(tài)屬性和方法。示例如下:

class A {
    foo: string = A.bar;
}

namespace A {
    export let bar = 'A';
    export function create() {
        return new A();
    }
}

const a: A = A.create();
a.foo; // 'A'
A.bar; // 'A'

4.4 命名空間與枚舉合并

同名的命名空間聲明與枚舉聲明可以進(jìn)行合并。這相當(dāng)于將枚舉成員與命名空間的導(dǎo)出成員進(jìn)行合并。示例如下:

enum E {
    A,
    B,
    C,
}

namespace E {
    export function foo() {
        E.A;
        E.B;
        E.C;
    }
}

E.A;
E.B;
E.C;
E.foo();

需要注意的是,枚舉成員名與命名空間導(dǎo)出成員名不允許出現(xiàn)同名的情況。示例如下:

enum E {
    A,                     // 編譯錯(cuò)誤!重復(fù)的標(biāo)識(shí)符 A
}

namespace E {
    export function A() {} // 編譯錯(cuò)誤!重復(fù)的標(biāo)識(shí)符 A
}

5、擴(kuò)充模塊聲明

對(duì)于任意模塊,通過(guò)模塊擴(kuò)充語(yǔ)法能夠?qū)δK內(nèi)的已有聲明進(jìn)行擴(kuò)展。例如,在“a.ts”模塊中定義了一個(gè)接口A,在“b.ts”模塊中可以對(duì)“a.ts”模塊中定義的接口A進(jìn)行擴(kuò)展,為其增加新的屬性。

假設(shè)有如下目錄結(jié)構(gòu)的工程:

C:\app
|-- a.ts
`-- b.ts

“a.ts”模塊文件的內(nèi)容如下:

export interface A {
    x: number;
}

“b.ts”模塊文件的內(nèi)容如下:

import { A } from './a';

declare module './a' {
    interface A {
        y: number;
    }
}

const a: A = { x: 0, y: 0 };

此例中,?“declare module ‘./a’ {}”是模塊擴(kuò)充語(yǔ)法。其中,?“‘./a’”表示要擴(kuò)充的模塊名,它與第一行模塊導(dǎo)入語(yǔ)句中的模塊名一致。

我們使用模塊擴(kuò)充語(yǔ)法對(duì)導(dǎo)入模塊“‘./a’”進(jìn)行了擴(kuò)充。第4行定義的接口A將與“a.ts”模塊中的接口A進(jìn)行聲明合并,合并后的結(jié)果仍為接口A,但是接口A增加了一個(gè)屬性成員y。

在進(jìn)行模塊擴(kuò)充時(shí)有以下兩點(diǎn)需要注意:

  • 不能在模塊擴(kuò)充語(yǔ)法中增加新的頂層聲明,只能擴(kuò)充現(xiàn)有的聲明。也就是說(shuō),我們只能對(duì)“‘./a’”模塊中已經(jīng)存在的接口A進(jìn)行擴(kuò)充,而不允許增加新的聲明,例如新定義一個(gè)接口B。
  • 無(wú)法使用模塊擴(kuò)充語(yǔ)法對(duì)模塊的默認(rèn)導(dǎo)出進(jìn)行擴(kuò)充,只能對(duì)命名模塊導(dǎo)出進(jìn)行擴(kuò)充,因?yàn)樵谶M(jìn)行模塊擴(kuò)充時(shí)需要依賴于導(dǎo)出的名字。

6、擴(kuò)充全局聲明

與模塊擴(kuò)充類似,TypeScript還提供了全局對(duì)象擴(kuò)充語(yǔ)法“declare global {}”?。示例如下:

export {};

declare global {
    interface Window {
        myAppConfig: object;
    }
}

const config: object = window.myAppConfig;

此例中,?“declare global {}”是全局對(duì)象擴(kuò)充語(yǔ)法,它擴(kuò)展了全局的Window對(duì)象,增加了一個(gè)myAppConfig屬性。第1行,我們使用了“export {}”空導(dǎo)出語(yǔ)句,這是因?yàn)槿謱?duì)象擴(kuò)充語(yǔ)句必須在模塊或外部模塊聲明中使用,當(dāng)我們添加了空導(dǎo)出語(yǔ)句后,該文件就成了一個(gè)模塊。

全局對(duì)象擴(kuò)充也具有和模塊擴(kuò)充相同的限制,不能在全局對(duì)象擴(kuò)充語(yǔ)法中增加新的頂層聲明,只能擴(kuò)充現(xiàn)有的聲明。

到此這篇關(guān)于TypeScript聲明合并的多種使用方式的文章就介紹到這了,更多相關(guān)TypeScript聲明合并內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vim快速合并行及vim 將文件所有行合并到一行

    Vim快速合并行及vim 將文件所有行合并到一行

    Vim是一個(gè)類似于Vi的著名的功能強(qiáng)大、高度可定制的文本編輯器,在Vi的基礎(chǔ)上改進(jìn)和增加了很多特性.這篇文章主要介紹了Vim快速合并行及vim 將文件所有行合并到一行,需要的朋友可以參考下
    2017-11-11
  • 深入理解JavaScript 參數(shù)按值傳遞

    深入理解JavaScript 參數(shù)按值傳遞

    本篇文章主要介紹了深入理解JavaScript 參數(shù)按值傳遞,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • 用JS實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲

    用JS實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲

    這篇文章主要為大家詳細(xì)介紹了用JS實(shí)現(xiàn)飛機(jī)大戰(zhàn)小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 分離式j(luò)avascript取當(dāng)前element值的代碼

    分離式j(luò)avascript取當(dāng)前element值的代碼

    比較不錯(cuò)的分離式j(luò)s代碼,獲取element的值,大家注意下,運(yùn)行后的效果是32之類的值,其實(shí)主要是沒(méi)有強(qiáng)制轉(zhuǎn)換成數(shù)字,所以大家可以加上
    2008-05-05
  • HTML+JavaScript實(shí)現(xiàn)筋斗云導(dǎo)航欄效果

    HTML+JavaScript實(shí)現(xiàn)筋斗云導(dǎo)航欄效果

    這篇文章主要為大家介紹了如何利用HTML+JavaScript+CSS實(shí)現(xiàn)筋斗云導(dǎo)航欄效果,當(dāng)鼠標(biāo)經(jīng)過(guò)某個(gè)li,筋斗云跟著到當(dāng)前的位置,感興趣的小伙伴可以試一試
    2022-03-03
  • Bootstrap按鈕下拉菜單組件詳解

    Bootstrap按鈕下拉菜單組件詳解

    這篇文章主要為大家詳細(xì)介紹了Bootstrap按鈕下拉菜單組件,感興趣的小伙伴們可以參考一下
    2016-05-05
  • 原生JS實(shí)現(xiàn)百葉窗特效

    原生JS實(shí)現(xiàn)百葉窗特效

    這篇文章主要為大家詳細(xì)介紹了原生JS實(shí)現(xiàn)百葉窗特效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • JavaScript實(shí)現(xiàn)動(dòng)態(tài)生成表格

    JavaScript實(shí)現(xiàn)動(dòng)態(tài)生成表格

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)動(dòng)態(tài)生成表格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • BootStrap輪播HTML代碼(推薦)

    BootStrap輪播HTML代碼(推薦)

    本文給大家分享bootstrap輪播h tml代碼,代碼簡(jiǎn)單易懂非常不錯(cuò),具有參考借鑒,需要的朋友參考下吧
    2016-12-12
  • JavaScript DOM節(jié)點(diǎn)操作方法總結(jié)

    JavaScript DOM節(jié)點(diǎn)操作方法總結(jié)

    下面小編就為大家?guī)?lái)一篇JavaScript DOM節(jié)點(diǎn)操作方法總結(jié)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-08-08

最新評(píng)論

宜川县| 重庆市| 遵化市| 镶黄旗| 和林格尔县| 通城县| 逊克县| 美姑县| 图木舒克市| 乌恰县| 宁晋县| 鄂尔多斯市| 浑源县| 康马县| 石阡县| 稷山县| 南汇区| 长沙县| 周宁县| 霍州市| 奎屯市| 黄石市| 鄄城县| 海伦市| 溆浦县| 庐江县| 安远县| 信丰县| 抚宁县| 和林格尔县| 渑池县| 奉节县| 通河县| 沂水县| 天津市| 永兴县| 方正县| 宝应县| 密云县| 贵州省| 长子县|