javascript - 您将如何在 typescript 中定义一个既是对象又是函数的类型?

标签 javascript typescript types prototype

看完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();

Playground link


顺便说一句,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/

相关文章:

Haskell 求完美平方——出现类型错误

c# - 我如何声明具有不同类型和未知类型的泛型列表以及如何使用仅在运行时已知的类型初始化泛型?

javascript - 如何在angularjs中获取响应数组值的asc顺序

javascript - 有没有更优雅的方法将 css 应用于 "all elements but this one"?

javascript - Angular 2 : Emit events across multiple components, 不仅仅是直接父级

typescript - 如何在 deno 中使用 HmacSHA256 创建哈希?

javascript - Angular 编译器 "compile"是什么?

javascript - 如何导入只有 JSDoc 注释的 JavaScript 模块

typescript - 是否可以在 TypeScript 中共享全局声明?

types - 如何在 TypeScript 中创建循环引用类型?