Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flowtype - how to write declaration for class factories, such as Backbone Models?

Extensive googling and reading through Flow docs and examples didn't show any example of a very common pattern in Javascript - having functions that return classes. A canonical example is Backbone:

var User = Backbone.Model.extend({
  getFullName: function() {
    return this.get('firstName') + ' ' + this.get('lastName');
  }
});  


var exampleUser = new User();
exampleUser.set('firstName', 'Johny'); //set() is a method from Backbone.Model
exampleUser.set('lastName', 'Something');
exampleUser.getFullName(); //method coming from User class

In JSDoc, I could annotate the class as follows, with some IDEs being able to figure out a decent autocompletion:

/**
 * @class User
 * @augments Backbone.Model
 */
var User = Backbone.Model.extend(/**@lends User.prototype */{
  getFullName: function() {...}
});

Is there any way how to properly annotate this pattern in Flow?

like image 544
Maros Urbanec Avatar asked Oct 08 '15 18:10

Maros Urbanec


1 Answers

/* @flow */

class Model {
    get(name: string): any {}
    set(name: string, value: any): void {}
}

function extend<T>(def: T): Class<Model & T> {
    throw new Error('not implemented')
}

var User = extend({
    getFullName: function() {
        return this.get('firstname') + this.get('lastname')
    }
})

var a = new User

a.get('firstname')
a.getFullName()
// a.notExisting give error

I use intersection type and generic type to express the pattern that 'Given a definition object type T, return a Class that is both Model and T'

This code compiles under brew-shipped flow 0.11


Below is my personal idea on flow. I have to agree that flow docs is scarce. The best way to learn its feature is probably reading flow's React annotation and flow's source. Flow is based on a sophisticated type inference algorithm, which allows you type-check a program without annotation. So Flow is designed to make you not annotate, and so does its documentation. However, type inference is not so advanced to free one from annotating. You code is an example.

like image 100
Herrington Darkholme Avatar answered Oct 27 '22 01:10

Herrington Darkholme