当前位置: 首页 > 知识库问答 >
问题:

在运行时确定回调函数的签名

徐博雅
2023-03-14
    interface IOne { (j: string): number; }
    interface ITwo { (j: number): number; }
    function dualArg(i: string, process: IOne | ITwo): number {
        // something like this
        if (process instanceof ITwo) {
            // call with numeric arg
            return process(i);
        } else {
            // conver to number
            return process(+i);
        }
    }
    function inc(i: number): number {
        return ++i;
    }
    function idem(text: string): number {
        return +text;
    }
    it('determine function signature', () => {
        expect(dualArg('1', inc)).toBe(2);
        expect(dualArg('1', idem)).toBe(1);
    })

如果我使用某种硬编码条件,例如process.prototype.constructor.name==='idem',我会得到Typescript错误消息:不能调用其类型缺乏调用签名的表达式。类型“iOne itwo”没有兼容的调用签名。

当然,我可以在这里定义process:any来禁用任何TypeScript检查,代码将编译并运行,但我的目标是能够仅通过签名来区分函数(而不依赖于其他约定,如名称或其他标志)。

共有1个答案

狄高畅
2023-03-14

问题是,在运行时,所有类型信息都丢失了。因此,您不能在运行时直接推断函数的类型(超出了它是函数的事实)。

您可以做的是创建一个函数类型,该函数类型也具有确定类型的属性。并使用函数来构建函数:

enum Type { One, Two}
interface IOne { (j: string): number; type: Type.One }
interface ITwo { (j: number): number; type: Type.Two}
function dualArg(i: string, process: IOne | ITwo): number {
    if (process.type === Type.One) {
        // Type guard above, process is of type IOne
        return process(i);
    } else {
        // Type guard above, process is of type ITwo
        return process(+i);
    }
}
function inc(i: number): number {
    return ++i;
}
function idem(text: string): number {
    return +text;
}

function oneFunction(fn: (j: string)=> number) : IOne{
    return Object.assign(fn, { type: Type.One as Type.One });
}

function twoFunction(fn: (j: number)=> number) : ITwo{
    return Object.assign(fn, { type: Type.Two as Type.Two });
}

dualArg("", twoFunction(inc));
dualArg("", oneFunction(idem));

对于您的简单示例来说,这可能有些过头了(您可以定义dualarg)的两个版本,但是如果函数的创建和用法相距甚远,并且在这两个版本之间重用了更多代码,那么这种方法可能是有意义的。

 类似资料:
  • 如上述示例代码,a是常规的Promise写法,现在想要改成b那样的async写法,请问该怎么办? 想要这么改的原因是函数内部的逻辑逐渐复杂,会调用多个Promise函数,常规写法会陷入层层嵌套的窘境,不利于维护。

  • 我正在尝试使用jersey 2/HK2自动绑定带有特定注释的工厂类。因此,我在运行时从泛型接口获取所提供的类型,然后尝试将工厂绑定到此类型。将工厂绑定到类的方法如下所示: HK2提供的方法定义如下: 当我用Eclipse构建所有东西时,这似乎工作得很好。然而,当我使用maven构建项目时,我会得到以下构建错误:

  • 问题内容: 给定具有以下结构的类。我试图确定由泛型方法的调用者分配的参数T的类型。 在C#中,我将使用“ default(T)”或“ typeof(T)”,但我试图在Java中执行此操作。谁知道/如何做?我真的不需要实例,我只需要Class定义。 问题答案: 你不能那样做。您可以做的是使方法签名如下: 然后,您可以使用给定的类检查类型。

  • 在以下代码中,设置状态后,setState方法的回调不会像预期的那样执行。如果你检查控制台,你会明白我的意思。console.log读取的状态不是更新的状态。它总是前一个(你可以通过点击读取数组按钮来检查这个),但是根据反应文档: setState()的第二个参数是一个可选的回调函数,它将在setState完成并重新呈现组件后执行。通常,我们建议对此类逻辑使用componentDidUpdate(

  • 问题内容: 创建活动后,我试图将动画应用于Android应用程序中的视图。为此,我需要确定视图的当前大小,然后设置动画以从当前大小缩放到新大小。这部分必须在运行时完成,因为视图会根据用户的输入缩放为不同的大小。我的布局以XML定义。 这似乎是一项容易的任务,显然有很多关于此的SO问题,尽管没有一个解决了我的问题。所以也许我缺少明显的东西。我可以通过以下方式理解我的观点: 这工作得很好,但打电话时,

  • 问题内容: 我正在尝试设置我的上传文件,这样,如果用户joe上传文件,它将转到MEDIA_ROOT / joe,而不是让每个人的文件都转到MEDIA_ROOT。问题是我不知道如何在模型中定义它。这是当前的外观: 所以我想要的不是“。” 作为upload_to,将其作为用户名。 我知道从Django 1.0开始,你可以定义自己的函数来处理upload_to,但是该函数不知道谁将成为谁,所以我有点迷路