在 TypeScript 中以类型安全的方式使用静态函数从外部库扩展 class
Extend a class from an external library with a static function in a typesafe manner in TypeScript
我想用 static 函数扩展 rxjs5 Observable
class。我可以简单地做到这一点 JavaScript:
var myStaticFn = function() { /* ... */ };
Observable.myStaticFn = myStaticFn;
这有效,但在 TypeScript 中我无法访问 Observable.myStaticFn
,因为 属性 myStaticFn
在 class Observable
上未知。
如何 declare/augment rxjs5 模块 Observable
class,以便我可以以类型安全的方式访问我的函数?
注意:作为起点,下面显示了如何将 non-static 函数扩展到 Observable 的示例(例如创建自定义rxjs 运算符),这完全有效,但不是我想要的!
function myOperator(this: Observable<any>): Observable<any> = function(){ /*...*/ };
Observable.prototype.myOperator = myOperator;
declare module "rxjs/Observable" {
interface Observable<T> {
myOperator: typeof myOperator;
}
}
上面的工作,因为 TypeScript 的 declare
语法允许我将 Observable
视为接口,接口可以是 augmented/merged。但是在 TypeScript 中没有办法在接口上声明一个 static 函数。
从 Observable
class 派生也不可行,比如 ExtendedObservable
因为我的代码的每个用户都必须使用 ExtendedObservable
类型而不是整个项目中的 Observable
类型,如果我想根据导入的模块在 Observable 上放置不同的静态方法,这个概念也会失败。
在 rx 的定义文件中,您有 Observable class and the ObservableStatic.
的定义
如果你想添加静态函数,那么你需要扩充 ObservableStatic
:
declare module "rxjs/Observable" {
interface ObservableStatic {
myOperator: typeof myOperator;
}
}
您需要声明一个与接口同名的模块。在模块内部编写静态函数。这是 TypeScript 中的最佳实践。它被称为"module merging"。
参考:Pro TypeScript 页 #40 #41
仅需注意一点:Microsoft 已将术语 "internal module" 更改为 "namespace",因为本书已写成:Namespaces
我自己找的 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;
}
}
请注意我是如何导入 myStaticFn
但在本地将其范围限定为名称 myStaticFnStatic
- 这是必需的,否则会出现编译错误。
我想用 static 函数扩展 rxjs5 Observable
class。我可以简单地做到这一点 JavaScript:
var myStaticFn = function() { /* ... */ };
Observable.myStaticFn = myStaticFn;
这有效,但在 TypeScript 中我无法访问 Observable.myStaticFn
,因为 属性 myStaticFn
在 class Observable
上未知。
如何 declare/augment rxjs5 模块 Observable
class,以便我可以以类型安全的方式访问我的函数?
注意:作为起点,下面显示了如何将 non-static 函数扩展到 Observable 的示例(例如创建自定义rxjs 运算符),这完全有效,但不是我想要的!
function myOperator(this: Observable<any>): Observable<any> = function(){ /*...*/ };
Observable.prototype.myOperator = myOperator;
declare module "rxjs/Observable" {
interface Observable<T> {
myOperator: typeof myOperator;
}
}
上面的工作,因为 TypeScript 的 declare
语法允许我将 Observable
视为接口,接口可以是 augmented/merged。但是在 TypeScript 中没有办法在接口上声明一个 static 函数。
从 Observable
class 派生也不可行,比如 ExtendedObservable
因为我的代码的每个用户都必须使用 ExtendedObservable
类型而不是整个项目中的 Observable
类型,如果我想根据导入的模块在 Observable 上放置不同的静态方法,这个概念也会失败。
在 rx 的定义文件中,您有 Observable class and the ObservableStatic.
的定义
如果你想添加静态函数,那么你需要扩充 ObservableStatic
:
declare module "rxjs/Observable" {
interface ObservableStatic {
myOperator: typeof myOperator;
}
}
您需要声明一个与接口同名的模块。在模块内部编写静态函数。这是 TypeScript 中的最佳实践。它被称为"module merging"。
参考:Pro TypeScript 页 #40 #41
仅需注意一点:Microsoft 已将术语 "internal module" 更改为 "namespace",因为本书已写成:Namespaces
我自己找的 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;
}
}
请注意我是如何导入 myStaticFn
但在本地将其范围限定为名称 myStaticFnStatic
- 这是必需的,否则会出现编译错误。