30

I've been using Basarats's excellent Collections library slightly updated for 0.9.0 creating types such as:

Dictionary<ControlEventType, 
    Dictionary<number, (sender: IControl, 
                        eventType: ControlEventType, 
                        order: ControlEventOrder, 
                        data: any) => void >>

Now I don't want to have to write this in full every time I use it. One of the approaches which seems to work is:

export class MapEventType2Handler extends C.Dictionary<ControlEventType,
                                                C.Dictionary<number,
                                                (sender: IControl,
                                                 eventType: ControlEventType,
                                                 order: ControlEventOrder,
                                                 data: any) => void >> {}

I can then write:

EH2: MapEventType2Handler = new MapEventType2Handler();

instead of:

EH: Dictionary<ControlEventType, 
        Dictionary<number, 
        (sender: IControl, 
         eventType: ControlEventType, 
         order: ControlEventOrder, 
         data: any) => void >>;

Anyone come across any better ideas?

I am also experimenting with 'typedeffing' various function signatures without great results.

andyks
  • 478
  • 1
  • 5
  • 9

2 Answers2

39

From version 1.4 Typescript supports type aliases (source, see also this answer):

type MapEventType2Handler = Dictionary<ControlEventType, 
    Dictionary<number, 
    (sender: IControl, 
     eventType: ControlEventType, 
     order: ControlEventOrder, 
     data: any) => void >>;
Community
  • 1
  • 1
splintor
  • 9,924
  • 6
  • 74
  • 89
  • [Advanced Types - Type Aliases](https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases) in the documentation. – user1338062 May 14 '17 at 04:22
3

First off thanks for the kind words :).

Your solution is actually optimal.

Long answer Typescript has two Declaration spaces. Types and Variables.

The only way to introduce items into the type declaration space is via a class or an interface ( 0.8.x could use module to introduce a type as well. Its removed from 0.9.x)

Interface will not work since you want the implementation to stay intact (and interface is implementation independent).

Variables will not work since they do not introduce a name in the Type Declaration space. They only introduce a name in the variable declaration space.

e.g.:

class Foo {    
}

// Valid since a class introduces a Type AND and Variable
var bar = Foo; 

// Invalid since var introduces only a variable so bar cannot be used as a type
// Error: Could not find symbol. Since compiler searched the type declaration space 
var baz: bar; 

// Valid for obvious reasons 
var x: Foo; 

What you want could be done if the language had a macros but for now class+extends is the only approach.

basarat
  • 261,912
  • 58
  • 460
  • 511