在 Typescript 中,为库中的类创建扩展方法

Jie*_*ang 8 typescript ionic-framework

我想向来自库的现有类添加一些方法。

已知一些基本类型,例如StringElement可以通过扩展interface并添加它的prototype.

interface String {
 extFunc():Function;
}

String.prototype.extFunc = function () {
  //blabla
};

"a".extFunc();
Run Code Online (Sandbox Code Playgroud)

我还找到了添加扩展方法的方法Observable<T>

declare module 'rxjs/Observable' {
  interface Observable<T> {
    foo: String;
  }
}
Observable.prototype.foo= "bar";
console.log(Observable.of("a").foo);
Run Code Online (Sandbox Code Playgroud)

但是当我尝试对 NavController(来自 ionic 的库)做同样的事情时,它将覆盖整个 NavController 到我声明的接口。

declare module 'ionic-angular' {
  interface NavController {
    replace(page: Page): Promise<any>;
  }
}
navCtrl.replace(...); //ok
navCtrl.push(...); //original function => "not exist"
Run Code Online (Sandbox Code Playgroud)

有谁知道向这些类添加扩展方法的最佳方法是什么?谢谢~

编辑: 有实际代码

import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';

import {GuidePage} from '../guide/guide.component';

@Component({
  selector: 'page-home',
  templateUrl: 'home.component.html'
})
export class HomePage {
  pageName = "home";

  // navCtrl is come from angular2's Dependency Injection,
  // it may not suitable to extend NavController
  constructor(public navCtrl: NavController) {}

  gotoGuide(): void {
    //wanna replace this
    this.navCtrl.push(GuidePage).then(() => {
      let index = this.navCtrl.getActive().index;
      this.navCtrl.remove(index - 1);
    });

    //with this custom extension method 
    //this.navCtrl.replace(GuidePage);
  }
}
Run Code Online (Sandbox Code Playgroud)

Jie*_*ang 7

好的,我参考这个答案并用以下代码解决我的问题。

polyfill.ts

import {Page} from 'ionic-angular/navigation/nav-util';
// the class we wanna create extension method
import {NavController} from 'ionic-angular/navigation/nav-controller';
// ionic provide this as NavController
import {NavControllerBase} from 'ionic-angular/navigation/nav-controller-base';

// add extension method on both class via interface
declare module "ionic-angular/navigation/nav-controller" {
  interface NavController {
    // replacePage?: typeof replacePage;
    replacePage(page: Page, data?: any);
  }
}
declare module "ionic-angular/navigation/nav-controller-base" {
  interface NavControllerBase {
    // replacePage?: typeof replacePage;
    replacePage(page: Page, data?: any);
  }
}

// define extension method 
function replacePage(this: NavController, page: Page, data?: any): Promise<any> {
  return this.push(page, data).then(() => {
    let index = this.getActive().index;
    this.remove(index - 1);
  });
}

// finally add this function to the class that ionic provide
NavControllerBase.prototype.replacePage = replacePage;
Run Code Online (Sandbox Code Playgroud)

用法:

constructor(private navCtrl: NavController)
foo(){
    this.navCtrl.replacePage(HomePage, {nextPage: OtherPage});
}
Run Code Online (Sandbox Code Playgroud)

通过这种方式在其他类上添加扩展方法,希望这对以后的人有所帮助。