怎么让Creator 支持 ts emitDecoratorMetadata 的参数?

RT. :smile:

1赞

请问需要这个选项做什么功能呢?

目前没有在支持的计划之列。

Creator 是用 babel 编译的,官方的 @babel/plugin-transform-typescript · Babel (babeljs.io) 插件不支持此选项,虽则有 https://github.com/leonardfactory/babel-plugin-transform-typescript-metadata ,但其存在缺陷: leonardfactory/babel-plugin-transform-typescript-metadata: Babel plugin to emit decorator metadata like typescript compiler (github.com) 。因此,为了稳定性,目前不打算做这个支持。

主要是在写一个开发框架,大量使用了装饰器,例如依赖注入时希望能少传入一个类型参数,能够极大提升开发体验。主要是 V2 版本时是好的,感觉 V3 如果能支持就更好了。

好的,了解,我们会继续观测。


另外以下是我个人观点(不代表 Creator 立场)。

这个功能并不能给出详尽的类型信息,只能用于非常简单的类型:


declare const some: PropertyDecorator;

class C { }

class D { }

const c = new C();

class Foo {
    @some
    foo = 0; // design:type - Object

    @some
    bar: typeof c = new C(); // design:type - Object

    @some
    baz: C = new C(); // design:type - C

    @some
    qaz: C | null = null; // design:type - Object

    @some
    quz: C | D = new C(); // design:type - Object
}

通过编译结果可以看到,只有 baz 能拿到有意义的类型。

是的,必须是具有单一实体类的变量声明才能拿到设计类型,类型数组都不行。不过多数时候这就够了,比如通过装饰器依赖注入一个单例:


@injectable
class FooService {
}

class Foo {
    @inject(FooService)
    fooService: FooService;
}

变量声明类型和提供给 @inject 的参数类型一定是一样的。这时如果支持获取设计类型,则就能少写一个 FooService,代码就简洁多了:


@injectable
class FooService {
}

class Foo {
    @inject
    fooService: FooService;
}

其实在使用 property 装饰器时很多时候都是用来拖拽映射节点或其上的 Component 的,这时可以用这个能力让开发者少写一个参数。当然需要数组和简单类型时就没办法了,可以作为可选项提供。


@ccclass("Foo")
class Foo {
    @property(Button) // 不支持时要求提供构造函数
    fooButtons: Button[] = [];
    @property // 支持时则可以省略
    fooLabel: Label;
}

1赞

大佬有解决这个问题不?

同问,目前开发在2.x上,想把专案搬移到3.x。