我有一些打字稿代码,我正在做一些元编程,我需要能够访问instance.func.name
,但是TypeScript在编译的JS中省略了函数名。
打字稿:
class ClassName {
// ...
func(): ReturnType {
// ...
}
}
编译JavaScript:
// ...
ClassName.prototype.func = function () {
// ...
};
所需的JavaScript:
ClassName.prototype.func = function func() {
// ... ^^^^
};
我是否缺少编译器选项,或者我可以在TypeScript中使用关键字来实现此目的?
答案 0 :(得分:7)
一个解决方案,我不会将其标记为已接受,因为它不提供name
属性,但可以使用任何其他标识符,如下所示:
function named(target: any, key: string) {
target[key].functionName = key;
}
class ClassName {
// ...
@named
func(): ReturnType {
// ...
}
}
然后访问instance.func.functionName
。
答案 1 :(得分:7)
无法使用TypeScript装饰器,因为function.name
为readonly property。
有一个hacky way:
class ClassName {
// ...
public func = function test() {
}
public func2() {
}
}
let instance = new ClassName();
console.log("RESULT", instance.func['name']);
但它并不完全符合您的要求(即在功能声明中注意缺少的原型)。
编辑:TypeScript编译器不会编写函数名称,因为emitter.ts中没有处理SyntaxKind.MethodDeclaration
:
function shouldEmitFunctionName(node: FunctionLikeDeclaration) {
if (node.kind === SyntaxKind.FunctionExpression) {
// Emit name if one is present
return !!node.name;
}
if (node.kind === SyntaxKind.FunctionDeclaration) {
// Emit name if one is present, or emit generated name in down-level case (for export default case)
return !!node.name || languageVersion < ScriptTarget.ES6;
}
}
如果您想弄清楚,那么您可以更新./node_modules/typescript/lib/typescript.js
文件。只需添加最后一个条件:
function shouldEmitFunctionName(node) {
if (node.kind === 173 /* FunctionExpression */) {
// Emit name if one is present
return !!node.name;
}
if (node.kind === 213 /* FunctionDeclaration */) {
// Emit name if one is present, or emit generated name in down-level case (for export default case)
return !!node.name || languageVersion < 2 /* ES6 */;
}
// MODIFIED
if (node.kind === 143 /* MethodDeclaration */) {
return true;
}
}
并运行它来测试更改:
$ node ./node_modules/typescript/lib/typescript.js hello.ts