2017-02-06 13 views
0

Я использую плагин flow-runtime для babel для генерации кода JavaScript с динамическим кодом. Ниже приведен рабочий процесс, я используюВнедрение интерфейса в Javascript с использованием flow-runtime

  • написать статический яваскрипта кода (с аннотациями потока)

  • компилировать этот код, используя столпотворение для преобразования аннотаций потока в typechecked кода

  • запустить этот скомпилированный код in node.js

Следующий рабочий процесс дает мне возможность писать машинописный код типа, но с типом che cking только там, где я хочу.

Итак, теперь мы понимаем, что я делаю, позвольте мне объяснить, что я пытаюсь достичь

я в основном нужно построить класс под названием Interface, который будет делать именно то, что это звучит. Этот класс будет расширен классами, которые должны быть интерфейсами, а затем расширены другими классами. Что-то вроде этого:

class Interface() { 
    constructor() { 
     ... 
    } 

    // interface superclass, supposed to be extended by all interfaces 
    // this class will provide all the utility methods required 
    // by an interface, such as validating the implementation of the 
    // interface, ... 

    validateInterfaceImplementation() { 
     ... 
    } 
} 

// interface definition 
class FooInterface extends Interface { 
    constructor() { 
     super(); 
     ... 
    } 
} 

// actual class, that will implement the "FooInterface" interface 
class Foo extends FooInterface { 
    constructor() { 
     super(); 
     ... 
    } 
} 

Теперь я хочу, чтобы обеспечить строгое выполнение FooInterface. Это означает, что я хочу, чтобы определить все методы, которые ожидается FooInterface interface, и подтверждение того, что все эти методы были реализованы классом Foo.

То, что я пытался выглядеть примерно так

// interface.js 
// @flow-runtime 
class Interface<T> { 
    constructor(t: T) { 
     (this: T); // let flow validate that the interface is implemented 
    } 
} 

// FooInterface.js 
// @flow-runtime 
type foInterface = { 
    bar(param: string): number; 
} 

class FooInterface extends Interface<fooInterface> { 
    constructor() { 
     super(fooInterface); 
    } 
} 

// Foo.js 
// @flow-runtime 
class Foo extends FooInterface { 

} 

new Foo(); // should throw an error, because the interface is not implemented 
      // (the function bar is not defined) 

Я сталкиваюсь с множеством проблем с этим подходом

  • Я не уверен, как реализовать универсальный класс Interface<T>. Думаю, моя реализация неверна, и скомпилированный код Babel также вызывает ошибку, но я не могу понять, как это сделать.
  • Я даже не уверен, будет ли этот метод работать или нет, или это лучший способ подойти к этой проблеме.

Любая помощь будет радушна. Заранее спасибо :)

ответ

1

С точки зрения потока 0.5.0 вы можете использовать ключевое слово Flow implements, объединенное с интерфейсами потока. Я думаю, что это даст вам то, что вы хотите, без необходимости создавать конкретные классы вообще:

// @flow 
// @flow-runtime 
interface IPoint<T> { 
    x: T; 
    y: T; 
} 

interface IJSON { 
    toJSON(): any; 
} 

class Point implements IPoint<number>, IJSON { 
    x: number = 123; 
    y: number = 456; 
    toJSON() { 
    return {x: this.x, y: this.y}; 
    } 
}