看完this answer对于 jQuery 的 $ 如何是一个函数和一个对象?
这个问题,它让我开始思考。你会如何在 typescript 中定义这种类型?
在常规 JS 中这是完全有效的:
var f = function() { alert('yo'); }
f.foo = "bar";
alert(f.foo); // alerts "bar"
f(); // alerts "yo"
但是在 typescript 中,f.foo
会抛出错误,Property 'foo' does not exist on type '() => void'
。
虽然您可以使用 bracket notation 获得类似的结果:
var f = function() { alert('yo'); }
f['foo'] = "bar";
alert(f['foo']); // alerts "bar"
f(); // alerts "yo"
这将完全绕过类型系统,并且为了类型安全, typescript 。
有没有一种方法可以在不违反 typescript 类型安全的情况下实现这种类型的功能?
最佳答案
您可以通过在接口(interface)上指定调用签名来定义这种类型:
interface MyFoo {
(): void;
foo: string;
}
在将对象赋给变量之前,您可以通过将函数转换为 any
来初始化对象:
let f: MyFoo = function() { alert('yo'); } as any;
f.foo = 'bar';
x();
顺便说一句,JQueryStatic
类型(即 $
变量的类型)在 JQuery defintions 中的定义类似:
interface JQueryStatic<TElement extends Node = HTMLElement> {
...
Deferred: JQuery.DeferredStatic;
...
(html: JQuery.htmlString, ownerDocument_attributes: Document | JQuery.PlainObject): JQuery<TElement>;
...
(selector: JQuery.Selector, context: Element | Document | JQuery | undefined): JQuery<TElement>;
(无法将链接内嵌,所以放在这里)
但是,这并没有多大帮助,因为您的问题也是如何使用这种类型初始化变量。 JQuery 库没有这个问题,因为它不是用 Typescript 编写的。
关于javascript - 您将如何在 typescript 中定义一个既是对象又是函数的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45861592/