我使用这样的文档化方法安装了knockout
个定义。
npm install @types/knockout
效果很好,我可以在任何地方导入它。
import * as ko from "knockout";
但是,我坚持使用某些自定义内容扩展KnockoutStatic
界面。我正在尝试迁移基于<reference ... />
和namespace
的大型TS应用程序以使用模块。在此之前,我轻松地将扩展接口声明为并且声明已合并。假设我的扩展名看起来像这样。
interface KnockoutStatic {
doSomething(): void;
}
我尝试创建一个KnockoutExtensions.d.ts
文件,我将其声明为这样。
import "knockout";
declare module "knockout" {
export interface KnockoutStatic {
doSomething(): void;
}
}
但是当我在某处导入knockout
和我的扩展程序时,TS仍然无法解析doSomething
次来电。
import * as ko from "knockout";
import "./KnockoutExtensions";
ko.doSomething(); // error
使用TypeScript 2.0和新的d.ts
子系统扩展库接口的正确方法是什么?
我正在使用安装了TypeScript 2.0的Visual Studio 2015 Update 3。
答案 0 :(得分:3)
问题是knockout
输入文件使用的是export =
语法,而且它不是&#34;增强友好&#34;。请参阅this作为参考。
对我来说最简单的解决方案是将扩展名包装在declare global { }
中,因为knockout
输入文件会声明全局范围内的所有内容。
declare global {
interface KnockoutStatic {
doSomething(): void;
}
}
答案 1 :(得分:2)
您可以轻松扩展'knockout'或任何其他TypeScript命名空间。
示例:创建knockout-extension.d.ts文件
/// <reference path="<path-to-typings-dir>/knockout/index.d.ts" />
declare module 'knockout' {
export interface CustomType {
customField: string;
customMethod(arg1: number, arg2: boolean): boolean;
}
namespace customNamespace {
export interface AnotherCustomType {
customField1: string;
customField2: boolean;
}
}
// NOTE: extending existing interface
export interface KnockoutStatic {
customMethod(): void;
}
}
注意:确保TypeScript编译器选择此文件。
使用扩展模块中新定义的类型。
// one way
import { CustomType } from 'knockout';
const foo: CustomType;
// second way
import * as kc from 'knockout';
const foo: kc.CustomType;
const bar: kc.customNamespace.AnotherCustomType;
有关模块和命名空间的更多信息,您可以检查Modules和Namespaces上的TypeScript文档并使用它们together。
干杯!
答案 2 :(得分:0)
您需要在模块外部创建界面。 不通过导出声明它。
module example {
//...do stuff
}
interface KnockoutStatic {
doSomething(): void;
}
您可以在文件中添加界面扩展名以保持其清洁。
答案 3 :(得分:0)
我发现winston
使用export =
语法也有同样的问题。当发现react
做同样的事情:https://www.credera.com/blog/technology-solutions/typescript-adding-custom-type-definitions-for-existing-libraries/时,我发现此页面很有帮助。
他们推荐的解决方案是这样的:
import 'react';
declare module 'react' {
interface OlHTMLAttributes<T> {
type?: "1" | "a" | "A" | "i" | "I";
}
}
只需导入模块,然后声明它即可允许此声明块中的任何接口扩展现有接口,并且在代码的其他部分,您可以像往常一样继续使用该接口;也就是说,您仍将导入react
或winston
或knockout
,并且您会看到这些新的界面成员。您不必开始引用自定义界面或类似的东西。
答案 4 :(得分:0)
此代码适用于我
// 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>;
}
}
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());