Better type annotation support for object initialization via "options" parameter in form of object literal

Topics: Language Specification
Dec 11, 2012 at 11:31 AM
Edited Dec 11, 2012 at 11:34 AM

Several Javascript libraries use the concept of 'default options' that may be passed to as constructor parameter. The constructor then uses a set of default parameters, but overrides all properties for which the given object has a value.

The following sample illustrates this pattern:

var canvas = new fabric.Canvas('c', {
  hoverCursor
: 'pointer',
  selection
: false
});

For handling this case right now I need the following TypeScript code:

 

declare var Canvas: {
        new (element: string, options: {
            containerClass?: string;
            defaultCursor?: string;
            freeDrawingColor?: string;
            freeDrawingLineWidth?: number;
            hoverCursor?: string;
            interactive?: bool;
            moveCursor?: string;
            perPixelTargetFind?: bool;
            rotationCursor?: string;
            selection?: bool;
            selectionBorderColor?: string;
            selectionColor?: string;
            selectionDashArray?: number[];
            selectionLineWidth?: number;
            targetFindTolerance?: number;
        }): Canvas;
    }

 

 

Thus, we need to duplicate the fields which are available on a specific class, as they are also set on the actual class definition itself (without the '?'):

 

interface Canvas extends StaticCanvas {
   
        // constructors
        (element: Element): Canvas;
        (element: string): Canvas;

        // fields
        containerClass: string;
        defaultCursor: string;
        freeDrawingColor: string;
        freeDrawingLineWidth: number;
        hoverCursor: string;
        interactive: bool;
        moveCursor: string;
        perPixelTargetFind: bool;
        rotationCursor: string;
        selection: bool;
        selectionBorderColor: string;
        selectionColor: string;
        selectionDashArray: number[];
        selectionLineWidth: number;
        targetFindTolerance: number;
        ...
}   

 

 

 

I think it would be nice to

a.) store such literal types using a name, so they can be re-used across multiple methods and b.) provide a way to prevent duplication at all, for example by mapping the actual type to a "shadow type" which is only used for initialization (see code sample below)

new (element: string, options*: Canvas);

// should allow the following use
var canvas = new fabric.Canvas('c', {
  hoverCursor: 'pointer',
  selection: false
});

I have seen the same pattern not only at fabric.js but also at other popular javascript libraries. Jquery is also such an example - in this case the predefined type defintion file for Jquery makes heavy use of 'any' so that all usages are allowed.

Kind Regards,
Oliver

Dec 17, 2012 at 7:45 PM

+1 for adding language support for common use cases like this.

Coordinator
Dec 18, 2012 at 4:48 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.