2013-11-18 4 views
0

У меня есть следующий HTML + TypeScript, который пытается создать экземпляр простого класса Point. При переходе по гиперссылке, я получаю следующие ошибки против каждой попытку пункта/улова:Ошибка времени выполнения TypeScript 'undefined'

Ошибки:

  • Не может прочитать свойство «Empty» неопределенные.
  • undefined не является функцией.
  • undefined не является функцией.

HTML:

<!DOCTYPE html> 

<html lang="en"> 
<head> 
    <meta charset="utf-8" /> 
    <title>TypeScript HTML App</title> 
    <script src="app.js"></script> 
    <script type="text/javascript"> 
     function Test() 
     { 
      try { alert(MyLibrary.Point.Empty.ToString()); } 
      catch (e) { alert(e.message); } 

      try { alert(new MyLibrary.Point(10, 20).ToString()); } 
      catch (e) { alert(e.message); } 

      try { alert(MyLibrary.Point.FromPoint(new MyLibrary.Point(10, 20)).ToString()); } 
      catch (e) { alert(e.message); } 
     } 
    </script> 
</head> 
<body> 
    <a href="javascript:Test();">Click Me</a> 
</body> 
</html> 

Машинопись:

module MyLibrary 
{ 
    export interface IPoint { X: number; Y: number; ToString(): string; } 

    export class Point implements MyLibrary.IPoint 
    { 
     private _X: number = 0; 
     private _Y: number = 0; 

     constructor(x: number, y: number) 
     { 
      this._X = x; 
      this._Y = y; 
     } 

     public get X(): number { return (this._X); } 
     public get Y(): number { return (this._Y); } 

     public ToString(): string 
     { 
      return ("{" + this._X.toString() + "," + this._Y.toString() + "}"); 
     } 

     public static FromPoint(point: MyLibrary.Point): MyLibrary.Point 
     { 
      return (new MyLibrary.Point(point.X, point.Y)); 
     } 

     private static _Empty: MyLibrary.Point = new MyLibrary.Point(0, 0); 
     public static get Empty(): MyLibrary.Point { return (MyLibrary.Point._Empty); } 
    } 
} 

машинописи отлично компилируется и проект нацелен на ECMA5. Не уверен, что происходит под капотом.

UPDATE: Код начинает работать, если я удаляю статические свойства из класса. Любые идеи, почему это так? генерируемый JavaScript для статических свойств выглядит следующим образом:

Object.defineProperty(Point, "Empty", { 
    get: function() 
    { 
     return (MyLibrary.Point._Empty); 
    }, 
    enumerable: true, 
    configurable: true 
}); 
Point._Empty = new MyLibrary.Point(0, 0); 
+0

Вот несколько способов управления вашим проектом TypeScript, чтобы вы не получили неопределенные значения: http://www.youtube.com/watch?v=KDrWLMUY0R0&hd=1 – basarat

+0

@basarat: У меня нет доступа к YouTube. Это видео доступно в другом месте? Возможно, я найду его, если вы скажете мне название. Благодарю. –

+0

Извините, что название «Модули TypeScript Demystified: Internal, AMD с RequireJS, CommonJS с NodeJS» – basarat

ответ

2

Вы не можете ссылаться на квалифицированное имя класса внутри модуля во время инициализации его статических членов - класс еще не доступен под этим именем. Измените эти две строки:

private static _Empty: MyLibrary.Point = new MyLibrary.Point(0, 0); 
    public static get Empty(): MyLibrary.Point { return (MyLibrary.Point._Empty); } 

Для этого

private static _Empty: MyLibrary.Point = new Point(0, 0); 
    public static get Empty(): MyLibrary.Point { return (Point._Empty); } 

Если вы проверяете код, сгенерированный вы можете видеть, что свойство MyLibrary.Point только получает значение после того, как происходит статическая инициализация класса. Это может считаться ошибкой компилятора.

+0

Спасибо. Я не знал о том, что конструкторы не могут быть вызваны во время статической инициализации.В другом примечании, почему считается лучшей и/или более чистой практикой статические члены в модуле с тем же именем. Разве это не позволит внешнему коду изменять значение Point.Empty, поскольку оно теперь является общедоступной переменной? –

+0

Просто перечисление обоих параметров, поскольку параметр модуля не имеет служебных издержек производительности. Либо может быть предпочтительнее в зависимости от сценария. –

+0

Интересно, я никогда об этом не думал. Это что-то, что, возможно, компилятор может обозначить как ошибку? –

1

Судя по сообщениям об ошибках модуля MyLibrary определяется во время выполнения, но класс точки внутри этого нет. Я предполагаю, что файл JS-файла находится в не загружается.

Поскольку вы не используете модули, каждый JS-файл с классами, которые вы хотите использовать, должен быть указан в верхней части вашего HTML-файла. Рассмотрите возможность использования параметра компиляции --out FILE для компиляции всех ваших классов в один файл, поэтому вам нужно только обратиться к этому файлу.

+0

Спасибо, но я не думаю, что это так, так как я могу перейти к файлу 'app.js' в браузере исходный вид. Как ни странно, код начал работать, когда я удалил статическое свойство 'Empty' из класса. Любые идеи относительно того, что происходит? –

+0

Пожалуйста, ознакомьтесь с обновлением в конце вопроса. Я включил сгенерированный JavaScript для статических свойств в случае, если это помогает. –

Смежные вопросы