Getting Type Info at Runtime?

Topics: General
Oct 1, 2012 at 7:45 PM

Here's an important scenario for me as a front end application framework author: given an object instance, I need to be able to determine it's fully qualified type. Now, I know there are no types in javascript. But, what I want to know is the module path. Is that possible?

Oct 1, 2012 at 10:06 PM

Thanks for the question! I believe that it is no more possible in TypeScript than it is in JavaScript. Just like in JS you may have to tag the object with the module it came from yourself in order to identify it later, perhaps by adding a special property during construction.

Oct 1, 2012 at 11:13 PM

Great. Since you answered my other question about module loaders...that's take care of (my custom version of require.js tags modules with that info). Great work on this project. I'm really, really excited about it.

Oct 2, 2012 at 4:55 AM

that RTTI also would include the names of interfaces, the types, the parent classes etc, the type values of parameters etc. this info is all known at transcompile time, but understandability not in the resultant javascript. However it would be great as an option to be able to have that RTTI information in some documented json structure tagged to the object.

Oct 2, 2012 at 8:43 PM
EisenbergEffect wrote:

Here's an important scenario for me as a front end application framework author: given an object instance, I need to be able to determine it's fully qualified type. Now, I know there are no types in javascript. But, what I want to know is the module path. Is that possible?


We had a similar need and we created a seperate type table for tracking this type of stuff. 

module Foo
   class Bar {
   }
   Types.registerType('Foo.Bar', Bar);
}


 
Types is another class with a static registerType() method that takes a string and a Class (essentially a function) as input.  Once registered in a simple map you can now lookup classes by either key (lookup against the map using "if (key in map)", or instance using "for (key in map) if (inst instanceof map[key]) return map[key];"
  
Oct 2, 2012 at 8:51 PM

If there is going to be support for RTTI, I would want to see this as opt-in at the compilation stage. I think this probably goes without saying though, but it has to be said.

Oct 2, 2012 at 9:02 PM

i agree with oisin, plus i may want to make that decision on a class by class , module by module or .ts by .ts file basic. just tagging a class name doesn't seem to be enough to me, i'd want the full structure that is getting lost during transcompilation. I'm very glad that typescript creates nice pithy JavaScript rather than automatically attaching some detailed structure  of everything to every object. But it would be useful. JavaScript by its nature kind of has built in reflection, however when adding this extra semantic layer, we need reflection against that layer. and attaching this in a consistent layer (with some helper functions to be able to interact with this metadata) would be invaluable. 

Oct 9, 2012 at 9:19 AM

Half of the party is discussing similar topics at: http://typescript.codeplex.com/discussions/397906

Oct 9, 2012 at 10:51 AM
EisenbergEffect wrote:

... Great work on this project. I'm really, really excited about it.

We can tell! :-)

Mar 13, 2014 at 6:19 PM
One way to implement this feature is to create a new emitter. We have the --declarations emitter. If the same information was emitted in JSON format, reflection would be solved. You do not need to pollute the emitted javascript just emit a second file that contains all public type info.

If this feature existed we could create powerful DI frameworks with typescript.
Coordinator
Mar 14, 2014 at 5:46 PM
I like this idea quite a bit. We've been brainstorming how to do reflection well, and it may just be that what you do is a JSON output and then consume that. It'd need to be smart enough to encode things like recursive types and definitions, but I could definitely see this being useful.
Mar 14, 2014 at 6:19 PM
Edited Mar 14, 2014 at 6:20 PM
The reflection json file would be worthless after minification unless a new compiler option was added that would preserve export names during minification.
module myModule{
    export class MyClass{
        foo:string = "";
        bar:number;
    }
}
Exports to:
window["myModule"];
(function (myModule) {
    var MyClass = (function () {
        function MyClass() {
            this.foo = "";
        }
        return MyClass;
    })();
    myModule["MyClass"] = MyClass;
})(window["myModule"] || (window["myModule"] = {}));
The class paths would be preserved.
Mar 15, 2014 at 6:05 PM
A .d.ts Parser would be good enough to retrieve that kind of information.
Mar 15, 2014 at 7:59 PM
A d.ts parser would work fine. It feels silly to parse something that was just parsed. Writing a parser is not for the faint of heart. If this info was exported to json we could use it for reasons other than reflection. It would be easy generate documentation or build extern/def files for haxe or java or c#
Mar 16, 2014 at 12:19 PM
See also: https://typescript.codeplex.com/discussions/483998

The output could be JSON schema

I'm not sure whether the meta data output will ever be safe to use on a minified script. When a script combined from multiple files is minified using a more advanced minifier then even public methods can be minified.

We would, however, dearly like to see this implemented because of its potential for use in testing and other non-runtime applications, such as documentation.
Mar 16, 2014 at 2:57 PM
The potential of .d.ts files is huge. You can generate documentation from it (comments can be included in .d.ts files) you can easily ship or load them with your application and generate RTTI on the fly or generate RTTI files in whatever format you prefer (JSON, XML, ...). What's holding you back to write such a parser?

At my company we are working on such tools (documentation generator, RTTI, ..) as part of a big project. Unfortunately it's unlikely they will be ready and available before 2015.
Mar 16, 2014 at 3:11 PM
Edited Mar 16, 2014 at 3:52 PM
You are right. The .d.ts file has everything I need. It would not be too hard to parse generated .d.ts files. Because I can expect the whitespace to be uniform, pattern matching is easy enough. It would be a complete nightmare to parse them based on the pure typescript spec. If I wanted to make use of the type info at runtime I would prefer the parser to be lean as to not weigh down the client. JSON is very lean because the browser comes with a built in parser.

I work for a tiny startup where I use typescript with AngularJS. I LOVE this combination. My main interest in this feature is to facilitate the creation a version of AngularJS that supports annotation based DI with typescript. The google team has built an impressive framework "AngularDart" on their Dart technology. I don't think Dart has a future but AngularDart shows the use of a powerful UI framework with type aware DI features and I am jealous.
Apr 26, 2014 at 6:26 PM
Like oisin mentioned, a compiler option is definitely needed. I would even take this a step further and say more than one option, because I may only care about the type names, and not the members and function parameters (just a smaller file), or perhaps I just want all types and members, but don't care about the function parameters. It's perhaps not that important, but thought I would mention it anyhow as well. ;)

Also, if you do export the RTTI (hopefully in JSON format for quick loading dynamically), please also have an option to include the comments. I'm creating a tool that could use the type information, but I would like to have the developers comments included with the types also (for intellisense-like reasons).
Apr 27, 2014 at 10:00 AM
You can get the types and their methods by using plain javascript features. Only for typing, parameter info and inheritance hierarchy TypeScript would be needed. I don't think, that TypeScript should include such things, because it would only make the compiler slower. If type information is needed, an additional tool could do the job as well.
Jul 2, 2014 at 1:54 AM
I believe it would be wise to take the proposal in this thread ( https://typescript.codeplex.com/discussions/542459 ) into account in the design of how to handle runtime type information.