Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declare interface of class only with methods signature without names

Suppose I have a class with many methods, but I know for sure that their signature matches.

Is it possible to describe the interface of this class without describing the specific methods of this class in it? Like here:

interface IController {
  (input: string): number // any method without reference to its name
}

class Controller implements IController {
  method1(input: string): number { ...do something }
  method2(input: string): number { ...do something }
  ...
}

Or is it impossible?

like image 337
revich2 Avatar asked Dec 25 '18 16:12

revich2


People also ask

Can TypeScript interface have methods?

A TypeScript Interface can include method declarations using arrow functions or normal functions, it can also include properties and return types. The methods can have parameters or remain parameterless.

How do you pass an interface as a parameter TypeScript?

An interface type cannot be passed as a parameter. When running TypeScript code, you are really compiling it down to JavaScript and then running the JavaScript. An interface is a TypeScript compile-time construct, so at runtime, there is no such thing as an interface type to call functions on or inspect properties of.

How do I create an interface in TypeScript?

Example: Interface and Objectsinterface IPerson { firstName:string, lastName:string, sayHi: ()=>string } var customer:IPerson = { firstName:"Tom", lastName:"Hanks", sayHi: ():string =>{return "Hi there"} } console. log("Customer Object ") console. log(customer. firstName) console.


1 Answers

The option to have an index signature (as @fk82 outlines in his answer) has the undesired consequence of forcing you to add an index signature to the class. This means that your class will be indexable by an arbitrary string, which might not be what you want.

If your goal is just to force the implementer class to only have methods with the given signature, a better option is to use a mapped type:

type IController<K extends PropertyKey> = { 
    [P in K]: (input: string) => number;
}

class Controller implements IController<keyof Controller> {
    method1(input: string): number { return input.length; }
    method2(input: string): number { return input === '' ? 0 : 1; }
}

let a = new Controller();
a['aa'] // not allowwed under no implicit any 

This has the bonus advantage of allowing the class to have some methods that do not conform to the signature if needed, but in an explicit way:

class Controller implements IController<Exclude<keyof Controller, 'special'>> {
    method1(input: string): number { return input.length; }
    method2(input: string): number { return input === '' ? 0 : 1; }
    special() { }
}
like image 62
Titian Cernicova-Dragomir Avatar answered Sep 30 '22 13:09

Titian Cernicova-Dragomir