Typescript: 'рдЯрд╛рдЗрдкрдСрдл рдлреВрдмрд╛рд░' рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ 'рдирдпрд╛ () => FooBarInterface' рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 16 рдЕрдкреНрд░реИрд▓ 2015  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: microsoft/TypeScript

рд╣рд╛рдп рджреЛрд╕реНрддреЛрдВ рдореИрдВ рдЯрд╛рдЗрдкрд╕реНрдХреНрд░рд┐рдкреНрдЯ рдРрдкреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдИрдУрд╕реА рдХрдВрдЯреЗрдирд░ рд╡рд┐рдХрд╕рд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдЬрд┐рд╕реЗ InversifyJS рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдореИрдВрдиреЗ TypeBinding<TServiceType> рдирд╛рдордХ рдПрдХ рд╡рд░реНрдЧ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ service type (рдЗрдВрдЯрд░рдлрд╝реЗрд╕) рдФрд░ implementation type (рд╡рд░реНрдЧ) рдХреЗ рдмреАрдЪ рдмрд╛рдзреНрдпрдХрд╛рд░реА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд░реНрдЧ рдХреЛрдб рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╣реИ:

// Defines allowed scope modes
enum TypeBindingScopeEnum {
  Transient,
  Singleton
}

class TypeBinding<TServiceType> {

    // The runtime identifier used because at runtime
    // we don't have interfaces
    public runtimeIdentifier : string;

    // The constructor of a class that must implement TServiceType
    public implementationType : { new(): TServiceType ;};

    // Cache used to allow singleton scope
    public cache : TServiceType;

    // The scope mode to be used
    public scope : TypeBindingScopeEnum;

    constructor(
      runtimeIdentifier : string,
      implementationType : { new(): TServiceType ;},
      scopeType? : TypeBindingScopeEnum) {

      this.runtimeIdentifier = runtimeIdentifier;
      this.implementationType = implementationType;
      this.cache = null;
      if(typeof scopeType === "undefined") {
        // Default scope is Transient
        this.scope = TypeBindingScopeEnum.Transient;
      }
      else {
        if(TypeBindingScopeEnum[scopeType]) {
            this.scope = scopeType;
        }
        else {
          var msg = `Invalid scope type ${scopeType}`;
          throw new Error(msg);
        }
      }
    }
}

рдореИрдВрдиреЗ TypeBinding<TServiceType> рд╡рд░реНрдЧ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╕рдВрд╕реНрдерд╛рдУрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рд╣реИ:

interface FooInterface {
  logFoo() : void;
}

interface BarInterface {
  logBar() : void;
}

interface FooBarInterface {
  logFooBar() : void;
}

// Notice default constructor
class Foo implements FooInterface {
  public logFoo(){ 
    console.log("foo"); 
  }
}

// Notice default constructor
class Bar implements BarInterface {
  public logBar(){ 
    console.log("bar"); 
  }
}

// Notice dependencies on FooInterface and  BarInterface on constructor
class FooBar implements FooBarInterface {
  public foo : FooInterface;
  public bar : BarInterface;
  public logFooBar(){ 
    console.log("foobar"); 
  }
  constructor(FooInterface : FooInterface, BarInterface : BarInterface) {
    this.foo = FooInterface;
    this.bar = BarInterface;
  }
}

рдореИрдВ TypeBinding<TServiceType> рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдЬрд┐рд╕рдореЗрдВ Foo рдФрд░ Bar рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реИ

var fooBinding = new TypeBinding<FooInterface>("FooInterface", Foo);
var barBinding = new TypeBinding<BarInterface>("BarInterface", Bar);

рдореЗрд░реА рд╕рдорд╕реНрдпрд╛ рддрдм рдЖрддреА рд╣реИ рдЬрдм рдореИрдВ { new(): TServiceType ;} рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ TServiceType рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рд╡рд░реНрдЧ рдХрд╛ рдирд┐рд░реНрдорд╛рддрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рд░рд╣рд┐рдд рдирд╣реАрдВ рд╣реИред

'рдЯрд╛рдЗрдкрдСрдлрд╝ рдлреВрдмрд╛рд░' рдкреНрд░рдХрд╛рд░ рдХрд╛ рддрд░реНрдХ 'рдирдпрд╛ () => рдлреВрдмрд╛рд░рдЗрдВрдЯрд░рдлреЗрд╕' рдкреНрд░рдХрд╛рд░ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд▓рд┐рдП рдЕрд╕рд╛рдЗрди рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдирд╣реАрдВ рд╣реИред

var fooBarBinding = new TypeBinding<FooBarInterface>("FooBarInterface", FooBar);

рдЗрд╕ рдореБрджреНрджреЗ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ?

рдзрдиреНрдпрд╡рд╛рдж :)

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рд╡рд░реНрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдмрджрд▓рдХрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдареАрдХ рдХрд░ рджрд┐рдпрд╛ рд╣реИ:

implementationType : { new(): TServiceType ;},

рдкреНрд░рддрд┐:

implementationType : { new(...args : any[]): TServiceType ;},

рдХреБрдЫ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рдХреЙрди рдХрдиреНрдлрд░реНрдо рд▓рд┐рдЦреЗрдВрдЧреЗред

рдзрдиреНрдпрд╡рд╛рдж...

рд╕рднреА 3 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рд╡рд░реНрдЧ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдмрджрд▓рдХрд░ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдареАрдХ рдХрд░ рджрд┐рдпрд╛ рд╣реИ:

implementationType : { new(): TServiceType ;},

рдкреНрд░рддрд┐:

implementationType : { new(...args : any[]): TServiceType ;},

рдХреБрдЫ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рдХреЙрди рдХрдиреНрдлрд░реНрдо рд▓рд┐рдЦреЗрдВрдЧреЗред

рдзрдиреНрдпрд╡рд╛рдж...

рдЪрд╛рд▓рд╛рдХ! рдЗрд╕ рдЪрд┐рдЯреНрдареА рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж :)

рдЗрд╕рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рдж, рдореИрдВ рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░реЛрдВ рдкрд░ рдЯрд╛рдЗрдкрдЪреЗрдХрд┐рдВрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдвреВрдВрдв рд░рд╣рд╛ рдерд╛ред { new(...args : any[]): T ;} рдиреЗ рдореБрдЭреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреАред

рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдореИрдВ рдбреЗрдХреЛрд░реЗрдЯрд░ рд▓рдХреНрд╖реНрдпреЛрдВ рдкрд░ рдЯрд╛рдЗрдкрдЪреЗрдХрд┐рдВрдЧ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ

function decor(oPar: {}): <TFunc extends { new (...args: any[]): A }>(target: TFunc) => void {    
    return function <TFunc extends { new (...args: any[]): A }>(target: TFunc): void {
        console.log(oPar, target);
    }
}

class A { id: string; }
// will error
@decor({})
class B { }

// Works
@decor({})
class C extends A { }

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

blendsdk picture blendsdk  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

uber5001 picture uber5001  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

seanzer picture seanzer  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

DanielRosenwasser picture DanielRosenwasser  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

manekinekko picture manekinekko  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ