是否可以在 TypeScript 中声明和调用函数字典?

Posted

技术标签:

【中文标题】是否可以在 TypeScript 中声明和调用函数字典?【英文标题】:Is it possible to declare and call a dictionary of functions in TypeScript? 【发布时间】:2016-04-04 11:07:10 【问题描述】:

我正在做一些重构,想知道是否可以声明和初始化工厂函数的字典,以枚举器为键,以便它可以用作工厂函数的查找然后可以调用?或者,或者,我是否走错了路并且错过了更优雅的解决方案。我跟着this answer 声明并初始化了一个类型化字典,但我不确定我是否已声明签名正确,例如键是数字而值是函数。我已将我的代码简化为一个非常通用的示例 - 我知道它相当做作,但这样的意图更加清晰。

// Types are enumerated as I have several different lists of types which I'd like to
// implement as an array of enumerators
enum ElementType 
    TypeA,
    TypeB,
    TypeC


// Here, I'm trying to declare a dictionary where the key is a number and the value is a
// function
var ElementFactory:  [elementType: number]: () => ; ;

// Then I'm trying to declare these factory functions to return new objects
ElementFactory[ElementType.TypeA] = () => new ElementOfTypeA();
ElementFactory[ElementType.TypeB] = () => new ElementOfTypeB();
ElementFactory[ElementType.TypeC] = () => new ElementOfTypeC();

// And finally I'd like to be able to call this function like so such that they return
// instantiated objects as declared in the code block above
var a = ElementFactory[ElementType.TypeA]();
var b = ElementFactory[ElementType.TypeB]();
var c = ElementFactory[ElementType.TypeC]();

【问题讨论】:

这基本上是正确的,但在您的类型定义中() => 说“这是一个接受零参数并返回 的函数”。您可能希望将该返回类型更改为比 更具体的类型,但请注意,您不能为各个索引指定不同的返回类型。 谢谢@DCoder,我相信这就是我所缺少的!你能把它放在一个答案中,我会把它标记为接受吗? 【参考方案1】:

您的代码大部分是正确的,并且这种方法会起作用,但有一点可以改进:

// Here, I'm trying to declare a dictionary where the key is a number and the value is a
// function
var ElementFactory:  [elementType: number]: () => ; ;

在类型定义中,() => 表示“一个接受零参数并返回 的函数”。您可以在此处修改返回类型更具体,但不幸的是,您仍然需要在调用这些工厂函数时手动表示返回值的类型。例如,您可以这样做:

type AnyElementType = ElementOfTypeA | ElementOfTypeB | ElementOfTypeC;

var ElementFactory:  [elementType: number]: () => AnyElementType; ;

...

// this type declaration will not work
var a: ElementOfTypeA = ElementFactory[ElementType.TypeA]();

// but these will
var b = <ElementOfTypeB>ElementFactory[ElementType.TypeB]();
var c = ElementFactory[ElementType.TypeC]() as ElementOfTypeC;

【讨论】:

以上是关于是否可以在 TypeScript 中声明和调用函数字典?的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript学习笔记 - 声明文件

如何在 TypeScript 中声明仅包含对象而不包含函数的类型

TypeScript 中是不是可以将强类型函数作为参数?

TypeScript 中是不是可以将强类型函数作为参数?

Decorators装饰器——TypeScript

TypeScript装饰器(decorators)