24

有没有一种方便的方法可以在模块内访问全局变量,而不会出现编译器错误,即下面使用的 CANVAS_WIDTH?

    export class Bullet {


        x: number = 22;
        y: number = 22;

        constructor (speed: number) {
            this.xVelocity = speed;
        }

        inBounds() {
            return this.x >= 0 && this.x <= CANVAS_WIDTH &&
                this.y >= 0 && this.y <= CANVAS_HEIGHT;
        };
}
}
4

3 回答 3

29

您需要将这些属性定义为静态,然后您可以像这样轻松访问它,

export class Game {
    static canvas: JQuery;
    static CANVAS_WIDTH: number;
    static CANVAS_HEIGHT: number;
    bullet: Bullet;

    constructor(canvasElem: JQuery) {
        Game.canvas = canvasElem;
        Game.CANVAS_WIDTH = Game.canvas.width();
        Game.CANVAS_HEIGHT = Game.canvas.height();
    }
}

export class Bullet {
    x: number = 22;
    y: number = 22;

    public inBounds() {
        // accessing static properties
        return this.x >= 0 && this.x <= Game.CANVAS_WIDTH && this.y >= 0 && this.y <= Game.CANVAS_HEIGHT;
    }
}

这编译为:

define(["require", "exports"], function(require, exports) {
    var Game = (function () {
        function Game(canvasElem) {
            Game.canvas = canvasElem;
            Game.CANVAS_WIDTH = Game.canvas.width();
            Game.CANVAS_HEIGHT = Game.canvas.height();
        }
        return Game;
    })();
    exports.Game = Game;

    var Bullet = (function () {
        function Bullet() {
            this.x = 22;
            this.y = 22;
        }
        Bullet.prototype.inBounds = function () {
            // accessing static properties
            return this.x >= 0 && this.x <= Game.CANVAS_WIDTH && this.y >= 0 && this.y <= Game.CANVAS_HEIGHT;
        };
        return Bullet;
    })();
    exports.Bullet = Bullet;
});
//# sourceMappingURL=dhdh.js.map
于 2012-12-11T15:09:28.250 回答
3

这是一个人为的例子,但不是试图推送到全局范围,您可以使用模块范围来封装一个变量,该变量将从多个类中使用。

module MyModule {
    var x: number = 5;

    export class FirstClass {
        doSomething() {
            x = 10;
        }
    }

    export class SecondClass {
        showSomething() {
            alert(x.toString());
        }
    }
}

var a = new MyModule.FirstClass();
a.doSomething();

var b = new MyModule.SecondClass();
b.showSomething();

关于使用相同变量的多个事物的所有常规规则在这里都适用——您不想在调用代码上强制执行特定的事件顺序。


编译为:

var MyModule;
(function (MyModule) {
    var x = 5;

    var FirstClass = (function () {
        function FirstClass() {
        }
        FirstClass.prototype.doSomething = function () {
            x = 10;
        };
        return FirstClass;
    })();
    MyModule.FirstClass = FirstClass;

    var SecondClass = (function () {
        function SecondClass() {
        }
        SecondClass.prototype.showSomething = function () {
            alert(x.toString());
        };
        return SecondClass;
    })();
    MyModule.SecondClass = SecondClass;
})(MyModule || (MyModule = {}));

var a = new MyModule.FirstClass();
a.doSomething();

var b = new MyModule.SecondClass();
b.showSomething();
于 2012-12-11T14:47:20.487 回答
1

我不确定我是否要鼓励这一点,但要从字面上回答 OP 的问题:

您可以将任何您想要的内容放入全局范围,然后在其他地方引用它。

例如,您可以在 index.html 等效项上添加以下内容:

function logit(x, loc) {
  if (console && console.log) {
    console.log(loc, JSON.stringify(x, null, '  '));
  }
}

现在,您可以通过至少两种方式之一在任何您想要的地方使用它。

混合您的全球范围。

(window as any).logit(item, "some location")

呜呜呜。

使用声明

您也可以使用declare.

所以在一个常规的 TypeScript 文件中:

declare const logit: (x: any, loc: string) => void;
// you could also just use
// declare const logit: any;

export default class MyClass {
  public handleIt(x: string) {
    logit(x, "MyClass.handleIt");
    // ... logic
  }
}

请注意,任何文件,不仅仅是“index.html”,都是公平的游戏,可以作为将内容推送到全局范围的启动点。请记住,如果您延迟加载模块,您可能会遇到麻烦。


你的例子

所以对你来说,你可以根据需要在全局范围内设置这两个值(或者可能是一个非 TypeScript 库为你做这件事,这几乎可以使它成为一个有效的用例),然后执行类似...

declare let CANVAS_WIDTH: number; // maybe const, I don't know your use case.
declare let CANVAS_HEIGHT: number;

export class Bullet {
  x: number = 22;
  y: number = 22;

  constructor (speed: number) {
    this.xVelocity = speed;
  }

  inBounds() {
    return this.x >= 0 && this.x <= CANVAS_WIDTH &&
    this.y >= 0 && this.y <= CANVAS_HEIGHT;
  };
}

但是,同样,这是高度反模式的,并且可能表明代码有异味。正如 Rajagopal 웃 所建议的那样,您希望在另一个类上具有静态值。

于 2020-06-25T15:01:31.660 回答