如何从模块导出函数作为类属性?
当类具有指向模块内函数的属性时,该属性的行为就像它的私有不管任何修饰符(添加public)此处不做任何操作)
例如,这里有3种方法来定义属性(a, b, c为例),都做同样的事情,但没有给我我想要的-这是在其他模块中定义函数,使类体不会失去控制
// myModule.ts
/** typedef this is a test */
export function func(msg) {
console.log(msg);
}
// myClass.ts
import * as myModule from './myModule';
export class MyClass {
a(msg) { return myModule.func(msg); }
b = (msg) => myModule.func(msg);
c = myModule.func;
}
// index.ts
import { myClass } from './myClass';
const classInstance = new myClass();
classInstance.a('test'); // works but this way i cannot get typedefs from a module
classInstance.b('test'); // added just for completness, but its same problem as c
classInstance.c('test'); // works but tsc complains about property 'c' does not exist on type 'MyClass'
开始挖掘-问题不是在完全在TypeScript项目中工作时,
问题是在将带有class的TS模块编译为JS时,然后从其他任何地方使用该JS
由TSC编译target=es2020
TSC隐藏属性,只有当typedefs可用时它们才可见
如果typedefs因任何原因不可用,属性.b
和.c
报告为does not exist on type MyClass
基本上,TSC创建的JS可以有效执行,但其他方面并不正确
myClass.js
export class MyClass {
constructor() {
Object.defineProperty(this, "b", {
enumerable: true,
configurable: true,
writable: true,
value: (msg) => myModule.func(msg)
});
Object.defineProperty(this, "c", {
enumerable: true,
configurable: true,
writable: true,
value: myModule.func
});
}
a(msg) {
return myModule.func(msg);
}
}
myclass.d.ts
export declare class MyClass {
a(msg: string): void;
b: (msg: string) => void;
c: typeof myModule.func;
}
当TSC用target=es5编译时,无论如何都可以
,因为它不依赖于Object.defineProperty
myClass.js
var MyClass = (function () {
function MyClass() {
this.b = function (msg) { return myModule.func(msg); };
this.c = myModule.func;
}
MyClass.prototype.a = function (msg) {
return myModule.func(msg);
};
return MyClass;
}());
你猜怎么着?使用target=esnext
, TSC生成完美的代码
myClass.js
import * as myModule from "./myModule";
export class MyClass {
a(msg) {
return myModule.func(msg);
}
b = (msg) => myModule.func(msg);
c = myModule.func;
}
,ES5ES2018但使用Object.defineProperty
定义每个属性,这是可怕的。和ESNext很干净。