Reputation: 7761
Is it possible to assign a function signature to a name?
For example, some external module provides an interface
interface ExtFunctionInterface {
(arg1: string, arg2: number): boolean
}
I would like to create a local interface or abstract class that assigns the above interface signature, to a method name. For example:
interface MyLocalInterface {
someMethodName typeof ExtFunctionInterface
}
or
abstract class MyLocalAbstractClass {
public abstract someMethodName typeof|signature of ExtFunctionInterface
}
So that when the interface is implemented or the class is extended:
class MyClass {implements|extends} MyLocal{Interface|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
}
}
This means that when ExtFunctionInterface is changed, the compiler would notify that the signature is incorrect.
Upvotes: 0
Views: 3776
Reputation: 249666
For interfaces, the answer is simpler then you might expect, just declare a field on the interface and you will get the desired behavior:
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;
}
}
For abstract classes you can define an abstract field, unfortunately you can't implement it as a member function, you need to do it as a field containing the function, which should be an ok work around in most cases:
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;
}
}
Note In the question you want the compiler to warn if there are fewer arguments, this is not the way typescript checks function compatibility (not just in this case, but in general). A function with fewer parameters will be compatible with a signature requiring more. Typescript will warn about argument type mismatch. For example :
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) {}
}
Upvotes: 1