2015-11-11 12 views
6

Mam trochę kodu maszynopisowego, i robię pewne metaprogramming, gdzie muszę mieć dostęp do instance.func.name, jednak TypeScript pomija nazwę funkcji w skompilowanym JS.TypeScript nie podając nazwy funkcji

maszynopis:

class ClassName { 
    // ... 
    func(): ReturnType { 
     // ... 
    } 
} 

Zestawione JavaScript:

// ... 
ClassName.prototype.func = function() { 
    // ... 
}; 

Pożądany JavaScript:

ClassName.prototype.func = function func() { 
    // ...       ^^^^ 
}; 

Czy istnieje opcja kompilator mi brakuje, lub słów kluczowych można używać w W celu wykonania tego należy użyć TypeScript?

Odpowiedz

5

rozwiązanie, po które nie zostaną zaakceptowane oznakowanie, ponieważ nie przewiduje właściwość name, ale nie działa z żadnym innym identyfikatorem jest następujący:

function named(target: any, key: string) { 
    target[key].functionName = key; 
} 

class ClassName { 
    // ... 
    @named 
    func(): ReturnType { 
     // ... 
    } 
} 

Wtedy dostęp instance.func.functionName .

+0

dość sprytnego rozwiązania – robsonrosa

6

Nie można używać dekoratorów TypeScript, ponieważ function.name to readonly property.

Jest hacky way:

class ClassName { 
    // ... 
    public func = function test() { 

    } 

    public func2() { 

    } 
} 

let instance = new ClassName(); 

console.log("RESULT", instance.func['name']); 

ale to nie jest dokładnie to, o co prosisz (tj zauważyć brakujące prototyp w deklaracji funkcji).

Edit: maszynopis kompilator nie pisać nazwę funkcji, ponieważ nie ma dla SyntaxKind.MethodDeclaration manipulacja w emitter.ts:

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; 
    } 
} 

Jeśli chcesz dostać w swoje ręce brudne, potem można zaktualizować ./node_modules/typescript/lib/typescript.js pliku. Wystarczy dodać ostatni warunek:

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; 
    }               
} 

i uruchomić to, aby przetestować zmiany:

$ node ./node_modules/typescript/lib/typescript.js hello.ts 
+0

Tak blisko, ale nie całkiem (brakujące proto). Nie wiedziałem, że TypeScript obsługuje to, co wygląda jak właściwości ES2016. Poręczny. – azz

+0

Zrobiłem jeszcze więcej kopania. Zobacz aktualizację. –

+0

Ładne znalezisko, przekaż. Muszę jednak nadal przechowywać TypeScript dla tego projektu. :( – azz

Powiązane problemy