2.0.8 const enum 支持问题

TypeScript 支持 常量枚举 const enum。常量枚举经过tsc编译后直接变成了对应的值,可以减小生成后的代码量,微软官方文档参考:http://www.typescriptlang.org/docs/handbook/enums.html

可是我在代码中写的常量枚举

const enum xxx{
    X1=0,
    X2=2,
    X3=3,
    X4=4,
}
let t:xxx=xxx.X1;

经Creator编译后生成的js代码如下:

var xxx;
(function (xxx) {
    xxx[xxx["X1"] = 0] = "X1";
    xxx[xxx["X2"] = 2] = "X2";
    xxx[xxx["X3"] = 3] = "X3";
    xxx[xxx["X4"] = 4] = "X4";
})(xxx || (xxx = {}));
var t = xxx.X1;

按照常量枚举的行为,这里应该只生成一行代码:

var t=0;/*X1*/

很明显,Creator没有把他当做一个常量枚举处理,而是当成了普通枚举处理了。
如果用vscode直接生成js代码,是没有问题的。
请官方人员给予答复。

取决于你是否用到了枚举?如果没用到,tsc 是可以优化的。如果用到了,就还是会像 Creator 那样。

我当然用到了啊,这个是确定的。
另外,手书上写的很清楚,这个属于语言特性,只要写成const enum 形式,它输出的形式是确定的,和有没有使用没关系,他不会生成xxx的代码,只会像c的宏一样,使用的地方直接替换成值。
另外请问,Creator调用的tsc是内置的吧,能给个版本号么?208的。

不是的,ts 支持枚举的反向查找,所以正常来说是会生成枚举字典的。目前的版本是 2.4.2

“不是的,ts 支持枚举的反向查找,所以正常来说是会生成枚举字典的”

普通的枚举支持反向查找没错,但常量枚举是不支持的!

首先,我们要搞清楚 普通枚举和常量枚举的区别:

请看微软官方文档:
http://www.typescriptlang.org/docs/handbook/enums.html
中文文档:
https://www.tslang.cn/docs/handbook/enums.html

有时候,枚举的item很多,item名称又很长,但不需要反向映射,但普通枚举生成了大量的映射代码

贴心的微软正好设计了const enum解决了这个问题,

这个常量枚举,我用vscode生成js代码,结果和文档上说的一样,但用Creator生成,结果变成了普通的枚举。
我的tsc版本是3.2.2:

哦…… 明白了!看来是 Creator 内置的 ts 版本过低导致的,我们有空升级一下

我翻了一下typescirpt的版本更新日志,发现 const enum是在1.4的版本加上去的。
微软官方更新日志在这里:
http://www.typescriptlang.org/docs/handbook/release-notes/typescript-1-4.html
同时,我将本地的tsc版本降低到2.4.2,用VsCode 测试,仍然是没有问题的。

重复一下问题的过程:

1,TS源码:

 const enum xxx{
    X1=0,
    X2=2,
    X3=3,
    X4=4,
}

console.log(xxx.X1);

2,经tsc编译后,正确的结果应该是:

console.log(0 /* X1 */);

如果将tsc编译开关preserveConstEnums 打开,正确的结果是这样的:

var xxx;
(function (xxx) {
    xxx[xxx["X1"] = 0] = "X1";
    xxx[xxx["X2"] = 2] = "X2";
    xxx[xxx["X3"] = 3] = "X3";
    xxx[xxx["X4"] = 4] = "X4";
})(xxx || (xxx = {}));
console.log(0 /* X1 */);

3,但经过Creator2.0.8编译后,得到的结果是这样的:

var xxx;
(function (xxx) {
    xxx[xxx["X1"] = 0] = "X1";
    xxx[xxx["X2"] = 2] = "X2";
    xxx[xxx["X3"] = 3] = "X3";
    xxx[xxx["X4"] = 4] = "X4";
})(xxx || (xxx = {}));
console.log(xxx.X1);

也就是说,Creator根本无视const的修饰

总结:

1,const enum 是在Typescript 1.4的版本添加上去的,所以2.4.2是支持的,我把本地的tsc降低到2.4.2,也没有发现问题,只有在Creator上出现了问题。因此,不能确定这个问题是Creator内置的tsc版本低引起的,也不能确定是编译开关preserveConstEnums引起的

2,到目前为止,Typescript 的版本已经升级到了3.3.3333,这个过程微软添加了很多好用的、实用的功能,你们确实应该升级了

3,该问题仍然未能确定原因出现在哪里,希望你们更新tsc版本后,能做详细测试,找到问题出现在哪里

1赞

typescript.transpileModule 接口下的编译选项 preserveConstEnums 不生效了
preserveConstEnums 设置为false,还是没办法剔除 const enum 的声明

应该是编译接口的 bug

直接用 tsc 编译是可以的

谢谢指出不足!

:slightly_smiling:

2.0.10 目前测试还是这个样子

2.0.10还是如此,请问creator将来会解决这个问题么?

1赞

2.1.1 已经升到 3.3.33333 了

仍然有围绕枚举的bug。
打个比方,
export enum InternalErrorEnum {
InternalErrorEnumStart,

//全局错误
SystemErrorStart,
Disconnected,//断开连接
Unlogined,//尚未登录
LoginFailed,//登录失败
SystemErrorEnd,

InternalErrorEnumEnd//内部错误Id的结束,也是外部错误Id的开始

}
这个一切正常
然后看这个
export enum ExternalErrorEnum {
ExternalErrorEnumStart = InternalErrorEnum.InternalErrorEnumEnd,

// WeaponProcesser
无武器信息,
武器等级到达上限,
武器升级失败_不存在该武器,
武器升级失败_货币数量不够,
武器升级失败_道具数量不够,
武器已到最大星级,
武器升星失败_不存在该武器,
武器升星失败_货币数量不够,
武器升星失败_道具数量不够,
武器升星失败_所需武器数量不够,
武器升星失败_不能使用已装备的武器升级,
武器升星失败_武器升级材料不存在,
武器升星失败_升星使用的武器星级小于当前武器升星所需星级,

ExternalErrorEnumEnd//内部错误Id的结束,也是外部错误Id的开始

}

这个就只有ExternalErrorEnumStart有值,其他的都是undefined。
同样的代码,tsc编译后在node.js服务端跑,一点问题都没有。

ts 目前就是用 tsc 编译的。你可以在资源管理器中找到 ts,右键菜单,打开 library 中的版本看看编译后的结果。

这BUG都2年了还是有问题啊,编辑器都3.+了还是支持不了常量枚举,无语了

最近开始接触cocos,用的3.5.1版本的creator,然后就发现了这个问题,论坛搜了一下果然有发现提出这个问题的帖子,请问官方啥时候能修一下这个问题,对重度项目来说减小的代码量还是很多的

这个特性我个人也觉得很有价值。
目前 3.x 受限于 babel 自身限制确实没办法支持 const enum,我记得很大一个原因是 babel 只是一个语法转换器,是逐脚本编译的,不存在项目的概念,因此无法处理跨文件的源码更新。编辑器导入一个脚本后,当引用到的 const enum 值变化时,确实也没办法收到通知并把里面的数字替换为新的数字。babel 目前很适合我们现在和将来对于编译流程的地址,也适合我们迁移到诸如 swc 的工具,因此暂时没有切换整体方案的计划。
或许将 const enum 延后到构建阶段编译,并且要对整个编辑器的脚本系统进行比较大的改动才能支持这个特性,因此目前优先级还没有很高,但我们会将这个需求提上议程。

该主题在最后一个回复创建后14天后自动关闭。不再允许新的回复。