最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Extend a class from an external library with a static function in a typesafe manner in TypeScript - Stack Overflow

programmeradmin2浏览0评论

I want to extend the rxjs5 Observable class with a static function. I can to this in plain JavaScript:

var myStaticFn = function() { /* ... */ };
Observable.myStaticFn = myStaticFn;

this works, but in TypeScript I can't aaccess Observable.myStaticFn as the property myStaticFn is not known on the class Observable.

How do I declare/augment the rxjs5 Module Observable class, so that I can access my function in a type-safe manner?

Note: As a starting point, the following shows an example how to extend a non-static function to the Observable (for example to create a custom rxjs Operator), and this pletely works but is not what I want!

function myOperator(this: Observable<any>): Observable<any> = function(){ /*...*/ };
Observable.prototype.myOperator = myOperator;

declare module "rxjs/Observable" {
    interface Observable<T> {
        myOperator: typeof myOperator;
    }
}

The above works, because the declare syntax of TypeScript allows me to treat the Observable as an interface, and interfaces can be augmented/merged. But there is no way in TypeScript to declare a static function on an interface.

It is also not feasible to derive from the Observable class, say ExtendedObservable because every user of my code would have to use the ExtendedObservable type instead of the Observable type throughout the project, and the concept additionally fails if I want to put different static methods on the Observable, depending on the imported modules.

I want to extend the rxjs5 Observable class with a static function. I can to this in plain JavaScript:

var myStaticFn = function() { /* ... */ };
Observable.myStaticFn = myStaticFn;

this works, but in TypeScript I can't aaccess Observable.myStaticFn as the property myStaticFn is not known on the class Observable.

How do I declare/augment the rxjs5 Module Observable class, so that I can access my function in a type-safe manner?

Note: As a starting point, the following shows an example how to extend a non-static function to the Observable (for example to create a custom rxjs Operator), and this pletely works but is not what I want!

function myOperator(this: Observable<any>): Observable<any> = function(){ /*...*/ };
Observable.prototype.myOperator = myOperator;

declare module "rxjs/Observable" {
    interface Observable<T> {
        myOperator: typeof myOperator;
    }
}

The above works, because the declare syntax of TypeScript allows me to treat the Observable as an interface, and interfaces can be augmented/merged. But there is no way in TypeScript to declare a static function on an interface.

It is also not feasible to derive from the Observable class, say ExtendedObservable because every user of my code would have to use the ExtendedObservable type instead of the Observable type throughout the project, and the concept additionally fails if I want to put different static methods on the Observable, depending on the imported modules.

Share Improve this question asked Oct 13, 2016 at 12:06 DynalonDynalon 6,81410 gold badges58 silver badges87 bronze badges 1
  • There is an open issue for the lack of static modifier on interfaces now github./Microsoft/TypeScript/issues/14600. – Marthinus Engelbrecht Commented Nov 18, 2018 at 13:56
Add a ment  | 

3 Answers 3

Reset to default 8

I found it out myself looking at the implementation of the static .from() extension in the RxJS source:

import { myStaticFn as myStaticFnStatic } from "./myStaticFn";

declare module "rxjs/Observable" {
    namespace Observable {
        let myStaticFn: myStaticFnStatic;
    }
}

Note how I import myStaticFn but scope it locally to the name myStaticFnStatic - this is required else you get a piler error.

In the definition file for rx you have the definition for the Observable class and the ObservableStatic.
If you want to add static functions then you need to augment the ObservableStatic:

declare module "rxjs/Observable" {
    interface ObservableStatic {
        myOperator: typeof myOperator;
    }
}

You need to declare a module with the same name of the interface. Inside the module you write the static functions. This is the best practice in TypeScript. It's called "module merging".

Reference: Pro TypeScript pages #40 #41

Just one notice: Microsoft has changed the term "internal module" to "namespace" since this book was wrriten: Namespaces

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论