Typescript声明顺序触发运行时错误

Typescript声明顺序触发运行时错误,typescript,Typescript,在寻找我遇到的一个问题时,我发现这样的说法,并且“转发声明”是不必要的 在我现在正在审查的一个项目中,这种说法似乎站不住脚。我将这个问题分解为一个简单的可复制示例,其中即使编译器没有抱怨,我们在运行时也会失败: $ cat bug.ts class A extends B { constructor(public id:number) { super(id); console.log("A():" + id); } } class B {

在寻找我遇到的一个问题时,我发现这样的说法,并且“转发声明”是不必要的

在我现在正在审查的一个项目中,这种说法似乎站不住脚。我将这个问题分解为一个简单的可复制示例,其中即使编译器没有抱怨,我们在运行时也会失败:

$ cat bug.ts
class A extends B {
    constructor(public id:number) {
        super(id);
        console.log("A():" + id);
    }
}

class B {
    constructor(public id:number) {
        console.log("B():" + id);
    }
}

var a = new A(12);

$ tsc  bug.ts
$ node  bug.js

/home/ttsiod/work/a/bug.js:4
    __.prototype = b.prototype;
                    ^
TypeError: Cannot read property 'prototype' of undefined
    at __extends (/home/ttsiod/work/a/bug.js:4:21)
    at /home/ttsiod/work/a/bug.js:8:5
    at Object.<anonymous> (/home/ttsiod/work/a/bug.js:15:3)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:901:3
$cat bug.ts
A类延伸至B类{
构造函数(公共id:编号){
超级(id);
log(“A():”+id);
}
}
B类{
构造函数(公共id:编号){
log(“B():”+id);
}
}
var a=新的a(12);
$tsc bug.ts
$node bug.js
/home/ttsiod/work/a/bug.js:4
__.原型=b.原型;
^
TypeError:无法读取未定义的属性“prototype”
at__扩展(/home/ttsiod/work/a/bug.js:4:21)
at/home/ttsiod/work/a/bug.js:8:5
反对。(/home/ttsiod/work/a/bug.js:15:3)
在模块处编译(Module.js:456:26)
在Object.Module.\u extensions..js(Module.js:474:10)
在Module.load(Module.js:356:32)
在Function.Module.\u加载(Module.js:312:12)
位于Function.Module.runMain(Module.js:497:10)
启动时(node.js:119:16)
在node.js:901:3

要么我遗漏了一个我不知道的关键字,要么“声明顺序不重要”的说法不像人们想象的那么笼统。

我对继承很重要。这并不重要,只要在使用前定义了它,你提到的链接就是这样

对于继承,B必须在A之前定义,以便A可以从B的原型复制成员


此外,“声明”(顺序不重要)和“定义”之间也有区别,在“定义”中,顺序几乎总是重要的,除了提升之类的情况。

如果继承是必要的,那么编译器不应该允许这种代码通过,这是不公平的吗?可以说,这不是吗,编译器错误?@ttsiodras进一步阐述了声明和定义之间的区别。这是JavaScript的本质,而且您选择加载生成的JavaScript的顺序可能完全取决于您,这使得执行此命令变得困难,因为它只在特定场景下工作。这很有趣,因为TypeScript足够聪明,如果它拆分成多个文件,就可以解决这个问题-当使用
--out
标志时,它会改变组合输出的顺序。@SteveFenton不,它不会,删除任何
///reference
并使用
tsc a.ts b.ts--out进行编译。js
a无论内容如何,每次都会出现在顶部。基本上,typescript从不进行任何语义排序,只通过
///reference
或传递给
tsc的文件顺序来尊重您的顺序是的-您是对的-实际上是我的参考文件中的顺序决定了排序(我写了我最大的TypeScript项目,当时引用注释是强制性的——所以我有一个
references.ts
文件来处理它们。)