这段TypeScript代码有什么用?

4
我正在阅读Typescript手册,发现了一段(对我来说)毫无意义的代码。有人能解释一下这段代码的目的吗?
取自文档
class Greeter {
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        if (this.greeting) {
            return "Hello, " + this.greeting;
        }
        else {
            return Greeter.standardGreeting;
        }
    }
}

var greeter1: Greeter;
greeter1 = new Greeter();
alert(greeter1.greet());

var greeterMaker: typeof Greeter = Greeter; // This line
greeterMaker.standardGreeting = "Hey there!"; // This line
var greeter2:Greeter = new greeterMaker(); // And this line
alert(greeter2.greet());

所以,文档中说var greeterMaker: typeof Greeter = Greeter“将保留类本身”。我也不是很确定这是什么意思。

然后它执行以下操作:

greeterMaker.standardGreeting = "Hey there!";

// Which does the exact same thing as this:
Greeter.standardGreeting = "Hey there!";

我在这里漏掉了什么?


2
我认为你没有漏掉任何东西。它们在一个变量中保存类的引用。他们使用该变量来修改类。这只是一种间接方式。在这种情况下,可以通过执行 Greeter.standardGreeting =“嘿!”; 来避免,但是想象一下将类传递给某个不知道它的模块,你就会明白了。 - Esteban
3个回答

2

这部分文档似乎试图解释一种 Greeting 类型和一种 typeof Greeting 类型之间的区别。

要理解这两个概念,首先必须了解 TypeScript 类是语法糖,它将 (1) 构造函数和 (2) 描述由该构造函数生成的实例的接口结合在一起。

因此,当您看到以下内容时:

class Greeter {
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        // ... code ...
    }
}

你实际上正在定义一些东西,如果用长篇大论的语言表述,看起来会更像这样:
interface Greeter {
  greet(): void;
}

var Greeter: {
  new(): Greeter;
  prototype: Greeter;
  standardGreeting: string;
};

Greeter = function () {};
Greeter.prototype.greet = function () {
  // ...code...
};

换句话说,您编写了一个描述Greeter实例的接口“Greeter”,以及一个附加到变量“Greeter”的第二个匿名类型,该类型描述构造函数。(这是因为类型存在于一个单独的、平行的命名空间中,不会与生成的代码中的变量名冲突。)
使用“Greeter”接口类型很明显——只需编写“Greeter”即可——但是如何访问附加到“Greeter”变量的此匿名类型呢?答案是“typeof”类型修饰符。编写“typeof Greeter”表示“使用变量Getter的类型”,这使我们可以访问分配给变量“Greeter”的持有构造函数的匿名类型。
所以这就是文档试图解释的内容。希望这个解释更清晰,现在我们可以理解代码的这一部分了。
// This creates an alias called `greeterMaker` to the
// Greeter constructor function
// (functions are objects, and objects are always handled
// by-reference in JavaScript)
var greeterMaker: typeof Greeter = Greeter;

// This modifies the `standardGreeting` property of the
// function through the alias
greeterMaker.standardGreeting = "Hey there!";

// This invokes the constructor function through the alias,
// constructing a new instance of a Greeter
var greeter2:Greeter = new greeterMaker(); // And this line

1
这是在TS的类型系统内工作,以获取对类的引用,而不直接声明greeterMaker为持有类(我想foo: class可能不被允许)。
理论上,即使右侧的值不是Greeter,而是具有类似语义和相同公共静态字段的其他类,这也将起作用。它可以允许您动态提供不同的类并使用它,但在此示例中并没有特别有用。

0
如果您运行代码,将会看到“Hello, there”应该在警告框中显示,接着是“Hey there!”。
在类Greeter中,静态变量不能被更改,除非创建一个新的类型。
如果您尝试添加以下代码: greeter.standardGreeting = "Hey there!"; 将会出现错误。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接