2015-11-20 2 views
0

Я пытаюсь написать библиотеку, которая проверяет функцию обратного вызова, а затем вызывает ее, когда она будет готова. Идея состоит в том, что вы можете включить JS асинхронно, а затем, когда он будет загружен, он проверит обратный вызов и выполнит его.Функция вызова дескриптора, которая может отсутствовать во время компиляции

Я использую машинопись. Следующий JS работает, но привычка компилировать в TS

if(typeof myFramework.ready === 'function') { 
    myFramework.ready(); 
} 

Затем разработчик с помощью библиотеки можно было сделать следующее:

var myFramework = myFramework || {}; // As the framework wont exists 
myFramework.ready = function(){//Execute developer's code}; 

Однако, используя машинопись Я получаю ошибку типа: Property «готов» не существует в типе 'typeof myFramework', что не является неожиданностью. Он компилируется, если я делаю следующее:

interface Window { 
    ready(): void; 
} 

if(typeof window.ready === 'function') { 
    window.ready(); 
} 

Но это означало бы добавление большего количества к объекту окна. И я предполагаю, что вызов глобального метода ready() вполне может стать точкой отказа!

Как бы вы это сделали?


Благодаря @ Джеймсе-межскважинной - как я классы в отдельных файлах файл, который имел обработку немного Ajax в посмотрел что-то вроде:

module MyFramework { 
    export interface IMyFramework { 
     ready? :() => any; 
    } 

    export class HasLoaded implements IMyFramework { 
     doReady = (framework: IMyFramework) => { 
      if(typeof framework.ready === 'function') { 
       framework.ready(); 
      } 
     } 
    } 

    var newHost: HasLoaded = new HasLoaded(); 
    newHost.doReady(MyFramework); 
} 

I может быть переосмысление логики, которая получила меня здесь, но это отдельная проблема!

ответ

0

Можно, конечно, объявить/экспорта интерфейсов модулей Typcript ... но они не будут использоваться пользователями вашей инфраструктуры, если эти пользователи также не используют TypScript (и имеют tsd для вашей структуры).

С этой оговоркой затем, следующий вариант на ответ от @gilamran выше работал на Typescript Playground:

module MyModule { 
    export interface IMyFramework { 
     ready? :() => any; 
    } 

    class MyFramework implements IMyFramework { 
    } 

    class YourFramework implements IMyFramework { 
     ready =() => { 
      alert("You're ready"); 
     } 
    } 

    export class Host { 
     doReady = (framework: IMyFramework) => { 
      if(typeof framework.ready !== 'undefined') { 
       framework.ready(); 
      }   
     } 
    } 

    var host: Host = new Host(); 
    host.doReady(new MyFramework()); 
    host.doReady(new YourFramework()); 

} 
+0

Спасибо, я дам это! –

0

Почему бы не определить функцию на вашем фреймворке, которую пользователь будет вызывать при загрузке? что-то вроде init(callback_to_developer_code);

Но если вы настаиваете на делать это ваш путь, вы просто должны определить дополнительное свойство на вашем рамочным класса интерфейс, как это:

interface IMyFramework { 
    ready? : Function; 
} 

class MyFramework implements IMyFramework { 
} 

var myFramework : MyFramework; 

if(typeof myFramework.ready !== 'undefined') { 
    myFramework.ready(); 
} 
+0

Спасибо за это. Я использую модули для определения myFramework на сегодняшний день (это в основном учебное упражнение, чтобы получить голову вокруг TS) - и я не верю, что могу добавить интерфейс к модулю? Приведенный выше код также сгенерировал ту же ошибку, которую я получал (свойство «ready» не существует в типе «MyFramework». Я не верю, что первое предложение будет работать при асинхронной загрузке myFramework.js as init() может не существовать –

+0

Я бы очень помог, если вы могли бы добавить больше кода и объяснить свою цель более подробно. – gilamran

0

Я новичок в машинописном поэтому, пожалуйста, не стесняйтесь игнорировать меня, но я лично предпочитаю проверять если тип является функцией, поскольку он более явный и безопасный (по крайней мере, в ванильном JS). Угадай, что это часть потрясающего TypeScript, которого я еще не знаю, но есть ряд вещей, которые могут быть ссылки, если они определены.

if (typeof method === 'function') { 
    method(); 
} 

Или вы могли бы, вероятно, уйти с:

method && method();