在 TypeScript 中扩展和定义函数签名

Posted

技术标签:

【中文标题】在 TypeScript 中扩展和定义函数签名【英文标题】:Extending and defining function signatures in TypeScript 【发布时间】:2018-07-18 00:25:59 【问题描述】:

是否可以将函数签名分配给名称?

例如,一些外部模块提供了接口

interface ExtFunctionInterface 
    (arg1: string, arg2: number): boolean

我想创建一个本地接口或抽象类,将上述接口签名分配给方法名称。例如:

interface MyLocalInterface 
    someMethodName typeof ExtFunctionInterface 

abstract class MyLocalAbstractClass 
    public abstract someMethodName typeof|signature of ExtFunctionInterface 

这样当实现接口或扩展类时:

class MyClass implements|extends MyLocalInterface|AbstractClass 

    // Correct impl
    public someMethodName(arg1: string, arg2: number): boolean 
        // impl
    

    // Compiler would complain that the function is not implemented
    // correctly because "arg2" is missing or type is wrong for e.g.
    public someMethodName(arg1: string): boolean 
        // impl
    


这意味着当 ExtFunctionInterface 改变时,编译器会通知签名不正确。

【问题讨论】:

【参考方案1】:

对于接口,答案比你想象的要简单,只需在接口上声明一个字段,你就会得到想要的行为:

interface MyLocalInterface 
    someMethodName : ExtFunctionInterface 


class MyClassFromInterfce implements MyLocalInterface 
    // Will satisfy the interface 
    public someMethodName (arg1: string, arg2: number): boolean 
        return false;
    
    // Will not satisfy the interface parameter is of the wrong type
    public someMethodName(arg2: number): boolean 
        return false;
    

对于抽象类,您可以定义一个抽象字段,遗憾的是您不能将其实现为成员函数,您需要将其作为包含该函数的字段来执行,这在大多数情况下应该是可以解决的:

abstract class MyLocalClass 
    abstract get someMethodName() : ExtFunctionInterface 


class MyClass extends MyLocalClass 
    // Ok 
    public someMethodName  = (arg1: string, arg2: number): boolean => 
        return false;
    
    // Not ok
    public someMethodName = (arg2: number): boolean => 
        return false;
    

注意在您希望编译器在参数较少时发出警告的问题中,这不是 typescript 检查函数兼容性的方式(不仅在这种情况下,而且在一般情况下)。具有较少参数的函数将与需要更多参数的签名兼容。 Typescript 将警告参数类型不匹配。例如:

class Base 
    method(arg1: string, arg2: number) 

class Derived extends Base 
    // We can override with fewer parameters 
    method(arg1: string) 
    // We can't override if parameter types are missmatched  
    method(arg1: number) 

    // We can override with more parameres if they are optional  
    method(arg1: string, arg2: number, arg3?: number) 
    // But not if they are required
    method(arg1: string, arg2: number, arg3: number) 

【讨论】:

感谢get 抽象类的“解决方法”很好。当它是一种方法而不是属性时,它会识别(TS 2.7.1)它......所以这正是我想要的。

以上是关于在 TypeScript 中扩展和定义函数签名的主要内容,如果未能解决你的问题,请参考以下文章

Typescript - 在保留签名的同时包装函数

TypeScript 具有相同参数的多种返回类型

Typescript - 具有通用类型函数的索引签名

Typescript + Express:类型“typeof e”没有兼容的调用签名

typeScript面对对象篇二

具有多个调用签名的 TypeScript 接口