[英]Exporting newable function from TypeScript declaration file
I'm trying to add typings for a library which has a new
able function, but finding it really difficult to do.我正在尝试为具有new
功能的库添加类型,但发现这真的很难做到。
With simply:简单地说:
export default function Api<T>(opts?: Settings): Api<T>;
I get "Only a void function can be called with the 'new' keyword" .我得到“只能使用 'new' 关键字调用 void 函数” 。 I'm aware of the new
keyword being valid in the declaration file, such as:我知道new
关键字在声明文件中是有效的,例如:
export default interface Api {
new<T=any>(opts?: Settings): Api<T>
}
That is just exporting a type, as the compiler says: "only refers to a type, but is being used as a value here" .这只是导出一个类型,正如编译器所说: “仅指一个类型,但在此处用作值” 。
I can't use a class here, since the API can be extended by plug-ins from other files, and type declaration merging doesn't work on classes (and I want the methods added by the other files to be able to typed by their own typing files as well).我这里不能使用类,因为 API 可以通过来自其他文件的插件进行扩展,并且类型声明合并不适用于类(我希望其他文件添加的方法能够通过他们自己的打字文件也是如此)。
I'm at a loss - any ideas?我不知所措 - 有什么想法吗?
I couldn't get the exact same error as you, but I was able to puzzle something together in TypeScript 4.3.5 that allows your default export to be an (augmentable) interface which you can still call regularly and use as a constructor:我无法得到与您完全相同的错误,但我能够在 TypeScript 4.3.5 中拼凑一些东西,使您的默认导出成为(可扩展的)接口,您仍然可以定期调用并用作构造函数:
api.d.ts api.d.ts
interface Settings {
setting?: string;
}
declare interface Api<T> {
getValue(): T;
<T>(opts?: Settings): Api<T>;
new<T>(opts?: Settings): Api<T>;
}
declare const Api: Api<any>;
export default Api;
index.ts索引.ts
import Api from './api';
// Augmentation the interface
declare module './api' {
export default interface Api<T> {
newField: number;
}
}
// Test the default export as Api instance
Api.getValue();
console.log(Api.newField);
// See if we can call/new the Api instance
const api = new Api<number>();
const api2 = Api<number>();
const api3: Api<number> = null!;
// Test the created instance as Api instance
const value: number = api.getValue();
console.log(api.newField);
The type of the Api
value is Api<any>
while the type of api
/ api2
/ api3
are all Api<number>
. Api
值的类型是Api<any>
而api
/ api2
/ api3
类型都是Api<number>
。 We can use .getValue()
on all of them, as well augment it with eg a .newField
property we can then read from all of them.我们可以对所有这些都使用.getValue()
,也可以使用例如.newField
属性来增强它,然后我们可以从所有这些属性中读取。
Basically since declare interface
creates just a type, I added a declare const
to also create the actual value that gets exported.基本上,因为declare interface
只创建一个类型,所以我添加了一个declare const
来创建导出的实际值。 Similar to how declare class
exports both the interface of a class instance along with the actual class as a value.类似于declare class
将类实例的接口和实际类作为值导出的方式。 I used two declares
followed by a export default
since TS doesn't allow you to export two defaults, even if one is purely a type and the other is purely a value.我使用了两个declares
然后是export default
因为 TS 不允许您导出两个默认值,即使一个是纯粹的类型而另一个是纯粹的值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.