Corey Alix
Corey Alix

Reputation: 2750

Any way to declare a nest class structure in typescript?

I'm interested in defining an existing framework (openlayers.d.ts) but cannot figure out how to express the fact that OpenLayers.Layer is both a class and a namespace for OpenLayers.Layer.Markers. I believe this makes Markers a nested class of Layer.

usage:

l = new OpenLayers.Layer(...); // this is a base class, never do this
m = new OpenLayers.Layer.Markers(...);

How would you declare both the Layer and Markers class in typescript?

Upvotes: 54

Views: 45149

Answers (6)

Fenton
Fenton

Reputation: 250922

You can use namespace/class merging to get an equivalent effect to nested classes. This example is adapted from Chapter 1 of Pro TypeScript.

You perform merging with a class and a namespace, or with a function and a namespace.

In all cases, the namespace must appear after the class or function for the merge to work.

Adapted example:

class Outer {

}

namespace Outer {
    export class Mid {

    }

    export module Mid {
        export class Inner {

        }
    }
}

var a = new Outer();
var b = new Outer.Mid();
var x = new Outer.Mid.Inner();

Upvotes: 15

Vad
Vad

Reputation: 4099

Use TypeScript's class expressions for this:

var OpenLayers = class {
    static Layer = class {
        static Markers = class {}
    }
}

Upvotes: 3

Marcelo Glasberg
Marcelo Glasberg

Reputation: 30879

As of 2016, I guess this is easier:

class A {
    static B = class { }
}

var a = new A();
var b = new A.B();

Upvotes: 8

sboisse
sboisse

Reputation: 5498

This seems like it has been fixed in versions 0.9.1.1 and later. You just have to create a module with the same name as the class where you want to nest types, and put your nested types in it.

More concretely, this is how you do it:

declare module a
{
    class b
    {
    }

    module b
    {
        class c
        {
        }
    }
}

var myB = new a.b();
var myC = new a.b.c();

This works as well when nesting types in typescript code with the export keyword:

export module a
{
    export class b
    {
    }

    export module b
    {
        export enum c
        {
            C1 = 1,
            C2 = 2,
            C3 = 3,
        }
    }
}

As mentioned by the user @recursive in the comments below, the order of declaration is important. So the class definition must be located before the module with the nested types.

Upvotes: 55

Leng
Leng

Reputation: 2019

This is a bit late but others may find it useful. This is how I did it to fool TS to accomplish the task.

declare module OpenLayers {
  interface Layer { 
   ....
  }

  interface Markers {
    ....
  }

  var Layer: {
    new(name:string, options?:any):Layer;
    prototype:Layer;
    Markers: { 
      new(params?:any):Markers;
      prototype: Markers;
    }
  }
}

var markers = new OpenLayers.Layer.Markers();

Upvotes: 6

user1793714
user1793714

Reputation: 329

Currently there is no support for nested classes.

http://typescript.codeplex.com/workitem/460

Upvotes: 6

Related Questions