typescript中聲明合并介紹
聲明合并
類型合并表明編譯器將合并兩個(gè)分開的并且名稱相同的聲明,合并之后的聲明擁有兩個(gè)聲明的特點(diǎn),任意數(shù)量的聲明可以被合并,不僅限兩個(gè)。
合并Interface
1.interface的非函數(shù)成員應(yīng)該是唯一的,如果兩個(gè)interface都聲明一個(gè)名稱相同但類型不同的非函數(shù)成員,編譯器將提示錯誤:
interface Box {
height: number;
}
interface Box {
height: string;
}
2.對于函數(shù)成員,每個(gè)相同名稱的成員被看作是相同名稱函數(shù)的重載,但是當(dāng)出現(xiàn)兩個(gè)interface時(shí),第二個(gè)有更高的優(yōu)先級,會覆蓋前一個(gè):
interface Cloner {
clone(animal: Animal): Animal;
}
interface Cloner {
clone(animal: Sheep): Sheep;
}
interface Cloner {
clone(animal: Dog): Dog;
clone(animal: Cat): Cat;
}
// 最終的排序是
interface Cloner {
clone(animal: Dog): Dog;
clone(animal: Cat): Cat;
clone(animal: Sheep): Sheep;
clone(animal: Animal): Animal;
}當(dāng)然這個(gè)規(guī)則有一個(gè)例外,當(dāng)函數(shù)的參數(shù)類型是一個(gè)單字面量類型(single string literal type),它將會根據(jù)優(yōu)先級排序,并放在聲明頂部:
interface Document {
createElement(tagName: any): Element;
}
interface Document {
createElement(tagName: 'div'): HTMLDivElement;
createElement(tagName: 'span'): HTMLSpanElement;
}
interface Document {
createElement(tagName: string): HTMLElement;
createElement(tagName: 'canvas'): HTMLCanvasElement;
}
// 字面量根據(jù)冒泡排序并放在了聲明頂部
interface Document {
createElement(tagName: 'canvas'): HTMLCanvasElement;
createElement(tagName: 'div'): HTMLDivElement;
createElement(tagName: 'span'): HTMLSpanElement;
createElement(tagName: string): HTMLElement;
createElement(tagName: any): Element;
}合并Namespace
- 合并兩個(gè)相同名稱的
namespace時(shí),將進(jìn)一步添加第二個(gè)namespace中導(dǎo)出的成員到第一個(gè)namespace。
namespace Animals {
export class Zebra {}
}
namespace Animals {
export interface Legged {
numberOfLegs: number;
}
export class Dog {}
}
// 合并到了第一個(gè)
namespace Animals {
export interface Legged {
numberOfLegs: number;
}
export class Zebra {}
export class Dog {}
}- 當(dāng)一個(gè)
namespace發(fā)生合并時(shí),和它合并的namesapce不能訪問它的未導(dǎo)出的成員:
namespace Animal {
const haveMuscles = true;
export function animalsHaveMuscles() {
return haveMuscles;
}
}
namespace Animal {
export function doAnimalsHaveMuscles() {
return haveMuscles; // Error, because haveMuscles is not accessible here
}
}
可以看到無法訪問haveMuscles,同時(shí)運(yùn)行也會報(bào)錯,可以結(jié)合編譯后的例子看:

namespace和class、enum、function合并
- 和合并
namespace一樣,class可以訪問namespace中導(dǎo)出的類型和值:
class Album {
label: Album.AlbumLabel;
}
namespace Album {
export class AlbumLabel {}
}namespace和function合并可以像javascript那樣在方法上添加屬性:
function buildLabel(name: string): string {
return buildLabel.prefix + name + buildLabel.suffix;
}
namespace buildLabel {
export const suffix = '';
export const prefix = 'Hello, ';
}
console.log(buildLabel('Sam Smith'));可以看編譯之后的代碼,可以看到直接在buildLabel上添加了屬性:

namespace和enum發(fā)生合并時(shí),namespace可以擴(kuò)展enum
enum Color {
red = 1,
green = 2,
blue = 4,
}
namespace Color {
export function mixColor(colorName: string) {
if (colorName == 'yellow') {
return Color.red + Color.green;
} else if (colorName == 'white') {
return Color.red + Color.green + Color.blue;
} else if (colorName == 'magenta') {
return Color.red + Color.blue;
} else if (colorName == 'cyan') {
return Color.green + Color.blue;
}
}
}可以看編譯之后的:

class之間不允許合并,但是如果需要模仿類似功能,可以參照 Mixins in Typscripts
Module擴(kuò)展
盡管Module之間是不支持合并的,但是你可以通過導(dǎo)入需要擴(kuò)展的方法,然后再更改它,這種方式去實(shí)現(xiàn):
// observable.ts
export class Observable<T> {
// ... implementation left as an exercise for the reader ...
}
// map.ts
import { Observable } from "./observable";
Observable.prototype.map = function (f) {
// ... another exercise for the reader
};但是這樣編譯器并不能提供良好的提示,所以需要擴(kuò)展module的聲明:
// observable.ts
export class Observable<T> {
// ... implementation left as an exercise for the reader ...
}
// map.ts
import { Observable } from "./observable";
declare module "./observable" {
interface Observable<T> {
map<U>(f: (x: T) => U): Observable<U>;
}
}
// 擴(kuò)展聲明
Observable.prototype.map = function (f) {
// ... another exercise for the reader
};
// consumer.ts
import { Observable } from "./observable";
import "./map";
let o: Observable<number>;
o.map((x) => x.toFixed());全局?jǐn)U展
如果在模塊中,也可以在全局聲明中來擴(kuò)展:
// observable.ts
export class Observable<T> {
// ... still no implementation ...
}
// 在這里擴(kuò)展
declare global {
interface Array<T> {
toObservable(): Observable<T>;
}
}
Array.prototype.toObservable = function () {
// ...
};到此這篇關(guān)于typescript中聲明合并介紹的文章就介紹到這了,更多相關(guān)typescript聲明合并內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript正則表達(dá)式中g(shù)標(biāo)志詳解
正則的思想都是一樣的,但是具體的寫法會有所不同,下面這篇文章主要給大家介紹了關(guān)于JavaScript正則表達(dá)式中g(shù)標(biāo)志的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-03-03
用javascript實(shí)現(xiàn)簡單計(jì)算器
這篇文章主要為大家詳細(xì)介紹了用javascript實(shí)現(xiàn)簡單計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
div失去焦點(diǎn)事件實(shí)現(xiàn)思路
blur只是針對form表單控件的,而對于 span , div , li 之類的,則沒辦法觸發(fā)它們的動作,本文有個(gè)示例,看看是怎么實(shí)現(xiàn)的2014-04-04
原生JS實(shí)現(xiàn)的跳一跳小游戲完整實(shí)例
這篇文章主要介紹了原生JS實(shí)現(xiàn)的跳一跳小游戲,結(jié)合完整實(shí)例形式分析了javascript實(shí)現(xiàn)跳一跳游戲的原理、實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2019-01-01

