我的应用程序支持第三方插件。 我在我的应用程序中都有方法,我想将这些方法归类到单个“ API”类下,以便将其呈现给插件。
例如,我有一个Todo
的{{1}}类。在运行时,我会自省Todo类,并将其所有方法添加到API类。所以我最终称呼
API ['deleteTodo'] = Todo ['deleteTodo']
我的插件现在可以愉快地调用deleteTodo(id)
了,一切正常。
但是,tsc发出API.deleteTodo(id)
,我必须发出2339: Property 'deleteTodo' does not exist on type 'typeof API'
。有没有一种简单的方法可以为//@TS-IGNORE
定义方法签名以消除错误并为插件作者提供API方法的自动完成功能?
我尝试让API用定义的那些方法实现接口,但这没什么区别。添加界面...
类API实现Todo
...给出API.deleteTodo
。
如果我添加了部分...
2420: class 'API' incorrectly implements 'Todo'. Property deleteTodo is missing...
...我仍然得到class API implements Partial <Todo>
对于亚伦...
2339: property 'deleteTodo' does not exist...
答案 0 :(得分:0)
您可能已经API
用Partial
实现了插件类,以允许方法成为undefined
,直到您将它们附加:
class API implements Partial<Todo>, Partial<SomePlugin> {
}
不幸的是,在使用方法之前,您需要检查是否已附加方法:
if(api.deleteTodo) {
api.deleteTodo(todo);
}
您还可以使用as
将API
实例转换为API & Todo
:
const api = new API() as API & Todo;
如果编译器认为api.deleteTodo
是一个函数,但在运行时它是undefined
,则可能导致错误。
答案 1 :(得分:0)
这里发生了几件事...
function deleteTodo() { }
class API {}
API['deleteTodo'] = deleteTodo;
API.deleteTodo(); // This succeeds at runtime, but tsc gives 2339: Property 'deleteTodo' does not exist on type 'typeof API'
该示例分配静态类方法(API.deleteTodo()
)而不是实例方法(new API().deleteTodo()
)和interfaces cannot define static properties。但是,除非您实际上有一些实例方法或属性(即您在某处使用new API()
),否则根本没有理由在这里使用类。
从示例中还不能完全清楚您是否具有预定的执行顺序。换句话说,您是否确保在任何地方使用API
之前,API.deleteTodo()
将拥有所有方法?如果是这样,那么我将分别定义API
类型,并使用断言来避免在构建值的代码中编译错误:
// Define the API
interface API {
deleteTodo(): void;
}
// Build the implementation
function deleteTodo() { }
const API: API = {} as API; // use `{} as API` to allow initializing an empty object
API["deleteTodo"] = deleteTodo; // fill in the API methods
// Now you can use it without any assertions
API.deleteTodo();
或者如果由于某些原因您确实需要使用类:
由OP编辑:这是我的用例的答案...
function deleteTodo() { }
interface API {
deleteTodo(): void;
}
class BaseAPI {
}
BaseAPI["deleteTodo"] = deleteTodo;
type APIClass = { new(): BaseAPI } & API;
const API = BaseAPI as APIClass;
new API(); // No use for this in your examples, but if you have a use for it...
API.deleteTodo();
也:
在运行时,我会自省Todo类,并将其所有方法添加到API类中。
尚不清楚Todo
类API是否提前知道。如果没有,那么以上将是不可能的。如果是这样的话,那么我不确定为什么为什么要静态地构建Todo
类呢?
function deleteTodo() {}
function otherMethod() {}
function etc() {}
const API = {
deleteTodo,
otherMethod,
etc
}
API.deleteTodo();
API.otherMethod();
API.etc()