TypeScript 中的类型声明顺序

20

TypeScript对类型声明顺序敏感吗?

更改类型的顺序会导致错误,这在 Angular 2 (beta.0) 内部会出现一个错误。据我所知,Angular 2 是使用 TypeScript 实现的(这就是为什么这个错误看起来如此奇怪和无关紧要):

angular2-polyfills.js:138 错误:无法读取未定义的 'prototype' 属性(…)

假设我们有一个名为 t1.ts 的文件:

export class AuthResponse extends JsonResponse { }
export class JsonResponse {
    public code: ResultCode;
}
export enum ResultCode { }

启动应用程序时,我们在客户端看到了上述错误。但是,如果我们反转此文件中的声明顺序,该错误将消失(仅供记录,目前我正在继续前进,并牢记这一点&它有效)。

要重现此错误,我们需要另外五个文件:

t2.ts

import {AuthResponse, JsonResponse, ResultCode} from './t1'; // this order?

export class DummyAction {
    doSomething() {
        console.log('test, starting ...');

        var v = new AuthResponse();
        return v;
    }
}

app.component.ts:

import {Component, OnInit} from 'angular2/core';
import {DummyAction} from './components/t2';            

@Component({      
    selector: 'root-app',
    templateUrl: '/app/templates/app.html',
})
export class AppComponent implements OnInit {
    constructor() {
        var tester = new DummyAction();
        // tester.runTest();
    }

    ngOnInit() { }
}

app.html:

<h1>TEST</h1>

boot.ts:

import {bootstrap} from 'angular2/platform/browser';
import {AppComponent} from './app.component';

bootstrap(AppComponent, []);

还有一个稍微大一点的文件index.html,但本质上与angular网站上的教程中的index.html结构相同。


1
我已经使用问题中提供的代码复现了这个问题。 - Kaveh Shahbazian
2个回答

16

TypeScript本身并不敏感,但它被编译为JS。

class A extends B {}
class B {}

在 JavaScript 中:

var A = (function (_super) { /* ... */ })(B);
var B = (function () { /* ... */  })();

第1行上B未定义。


6
TypeScript不敏感于声明顺序,但它为什么还要输出这样的JavaScript代码呢?它应该知道得更好才对。我在这里漏掉了什么? - stakx - no longer contributing
1
TypeScript本身不敏感,但编译成JS后可能存在问题。这意味着tsc不合规吗? - Paul Draper

9

我已经投票支持vasa_c的答案,因为它是正确的。下面我想提供更多关于这个问题的信息,以便原帖作者更容易地理解。

如果我们看一下你的示例代码:

export class AuthResponse extends JsonResponse { }
export class JsonResponse {
    public code: ResultCode;
}
export enum ResultCode { }

编译它 - 最终结果将是这样的:

var AuthResponse = (function (_super) {
    __extends(AuthResponse, _super);
    function AuthResponse() {
        _super.apply(this, arguments);
    }
    return AuthResponse;
})(JsonResponse);
exports.AuthResponse = AuthResponse;
var JsonResponse = (function () {
    function JsonResponse() {
    }
    return JsonResponse;
})();
exports.JsonResponse = JsonResponse;
(function (ResultCode) {
})(exports.ResultCode || (exports.ResultCode = {}));
var ResultCode = exports.ResultCode;

请注意,生成的代码不仅仅是函数定义,它同时包含了变量。这一点非常重要,因为你既有声明又有表达式。关于这个问题以及为什么在js中表达式的顺序很重要,你可以阅读这篇优秀文章: JavaScript函数声明和评估顺序

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