2016-08-18 70 views
2

我有許多類的重複類裝飾家庭。一些與此類似:如何編寫多個TypeScript類裝飾器?

@foo 
@bar 
@baz 
export class MyClass { /* ..... */ } 

由於我使用的是在多類這三個裝飾,我真的想打破這種分解成一個裝飾,比如:

@standard 
export class MyClass { /* ... */ } 

我已經試圖創建一個新類裝飾者鏈裝飾要求是這樣的:

export function standard<ReturnType>(ctor: Constructor<ReturnType>) { 
    return baz(bar(foo(ctor))); 
} 

打字稿手冊說,應用多種裝飾應該評估類似於函數組合,WH這就是爲什麼我認爲我應該能夠將它們鏈接在一起。然而,來編譯時間(使用打字稿1.8)我得到類似

Unable to resolve signature of class decorator when called as an expression. Type 'Constructor<ReturnType>' is not assignable to type 'void'.

有沒有一種方法,我可以構建這種「包裝」裝飾,簡化我的代碼錯誤?

+2

當我填入空格時,您的代碼對我來說工作正常。你能發佈一個完整的例子來重複你的錯誤嗎? –

+1

試圖給你一個更好的例子,讓我找到解決辦法!查看下面的答案。 –

回答

1

在試圖建立我的@大衛問題的更完整的版本,我想通了,我要去哪裏錯了。

更,完整的例子:

interface Constructor<T> { new(...args: any[]): T } 
interface A { a: number; } 
interface B { b: number; } 
interface C { c: number; } 

function foo(Target: Constructor<A>): Constructor<A>{ 
    // do some stuff to the constructor 
    return Target; 
} 
function bar(Target: Constructor<B>): Constructor<B> { 
    // do some stuff to the constructor 
    return Target; 
} 
function baz(Target: Constructor<C>): Constructor<C> { 
    // .... 
    return Target; 
} 

function standard(ctor: Constructor<A & B & C>): Constructor<A & B & C> { 
    return baz(bar(foo(ctor))); 
} 

@foo 
@bar 
@baz 
class MyClass implements A, B, C { a=1;b=2;c=3;d=6; } 

有我的實際代碼一些隱式類型是有點向我隱藏的問題。顯然,我無法正確讀取編譯器輸出。

的問題是與我如何述說我的裝飾:

function foo(Target: Constructor<A>): Constructor<A> { } 

需要進行

function foo<T extends A>(Target: Constructor<T>): Constructor<T> {} 

我發現,如果我在裝飾設置返回類型any編譯錯誤就走開了。額外的泛型參數讓類型信息乾淨地流過裝飾器。否則,我相信它看到(實質上)Constructor<MyClass>不能被分配Constructor<A>的實例(因爲A缺少其他接口)。也奇怪的是,如果我在MyClass中添加了d的聲明,我在裝飾器中彈出更多錯誤。

因此,在結束時 - 使用類裝飾器時,請注意您的泛型,或者僅返回any

0

你可以嘗試把它像這樣:

export function foo(target: any) 
{ 
    return target; 
} 

export function bar(target: any) 
{ 
    return target; 
} 

export function baz(target: any) 
{ 
    return target; 
} 

export function standard<T>() 
{ 
    return (target: { new(): T}) => 
    { 
     return foo(bar(baz(target))); 
    } 
} 

@foo 
@bar 
@baz 
export class MyClass { /* ... */ } 

@standard<MyClass>() 
export class MyClassA { /* ... */ }