我已经创建了一个自定义Knockout扩展程序,但我在扩展Knockout定义文件提供的现有界面时遇到了问题。
增量剂/ Numeric.ts
var i=0;
Boot.ts
import * as ko from "knockout";
function Extender(target: KnockoutObservable<number>, options: IOptions = {}): KnockoutObservable<number> {
// ...
};
interface IOptions {
// ...
}
export {Extender as NumericExtender, IOptions as INumericExtenderOptions}
为了让编译器了解import * as ko from "knockout";
import {NumericExtender} from "./Extenders/Numeric";
class Boot {
public constructor() {
ko.extenders.numeric = NumericExtender;
}
}
,我需要扩展现有的接口:
ko.extenders.numeric
现在我遇到了麻烦。要访问interface KnockoutExtenders {
numeric(target: KnockoutObservable<number>, options?: INumericExtenderOptions): KnockoutObservable<number>;
}
,我需要INumericExtenderOptions
声明:
import
但是当添加import语句时,该文件被视为一个模块which makes it impossible to extend an existing interface。
有没有办法做到这一点,还是我需要将import {INumericExtenderOptions} from "./Extenders/Numeric";
移到定义文件中以避免IOptions
?
答案 0 :(得分:2)
好像您正在使用全局版本的淘汰声明文件。我认为不可能在模块声明文件中扩展全局范围中定义的接口。有几种解决方案:
我认为最简单的解决方案是将您的界面置于全局命名空间。对于IOptions,这变为:
// index.d.ts
interface IOptions {
// ¯\_(ツ)_/¯
}
interface KnockoutExtenders {
numeric(target: KnockoutObservable<number>, options?: IOptions): KnockoutObservable<number>;
}
现在您可以在任何地方使用数字函数访问IOptions和KnockoutExtenders,因为声明文件仍然是全局的。
另一种解决方案是拉入模块版本(我认为这是我首选的解决方案,因为你没有用所有的淘汰类型污染全局命名空间)。在淘汰的情况下:typings install --save knockout
。然后,您必须在需要时专门导入所需的类型。例如。你的数字变成了
// src/numeric.ts
import { Observable } from "knockout"
export function Extender(target: Observable<number>, options: IOptions = {}): Observable<number> {
// ¯\_(ツ)_/¯
};
export interface IOptions {
// ¯\_(ツ)_/¯
}
然后你可以在另一个声明文件中扩充淘汰赛模块。例如:
// index.d.ts
import { Observable } from "knockout"
import { IOptions } from './src/numeric'
declare module "knockout" {
interface Extenders {
numeric(target: Observable<number>, options?: IOptions): Observable<number>
}
}
然后,您应该可以在应用程序的任何位置使用增强的扩展器界面:
// src/boot.js
import { extenders } from "knockout"
import { Extender } from "./numeric"
class Boot {
public constructor() {
extenders.numeric = Extender
}
}
最终的解决方案,可能是最好地解决您的问题,是使用模块化声明文件,但扩充全局模块。您的numeric.ts保持不变,您的声明文件变为:
import { IOptions } from './src/numeric'
declare global {
interface KnockoutExtenders {
numeric(target: KnockoutObservable<number>, options?: IOptions): KnockoutObservable<number>
}
}
有关详细信息,请查看page on declaration merging from the typescript handbook.