4

Let's say I have some C# DTO's and I want to convert them to TypeScript interfaces using T4 templates and neat little library called TypeLite

On the client side, I have some concrete TypeScript classes (that inherit from Backbone.Model but that's not important) that represent the same DTO defined on the server side.

The intended goal of the interfaces is to act as data contracts and ensure client and server DTOs are kept in sync.

However, this is problematic since TypeScript supports no run-time type checking facilities other than instanceof. The problem with instance of is when I fetch my DTOs from the server they are plain JSON objects and not instances of my model. I need to perform run-time type checking on these DTOs that come in from the server as JSON objects.

I know I can do something like this:

collection.fetch({...}).done((baseModels) => {
     baseModels.forEach((baseModel) => {
           if(baseModel&& baseModel.SomeProperty && baseModel.SomeOtherProperty){
                //JSON model has been "type-checked"
           }
     });
});

However, there is obvious problems to this because now I need to update in three places if I change or add a property.

Currently the only thing I found is this but it's undocumented, not maintained, and uses node which I have zero experience with so I'll save myself the frustration. Does anybody know of anything similar to perform run-time type checking in TypeScript or some other way to accomplish what I'm after?

It would be great if this was built into TypeLite to generate the interfaces as well as a JSON schema for type checking at run-time. Being that this project is open source somebody should really go ahead and extend it. I'd need some pointers at the least if I would do it myself (thus the question).

More details about my particular problem here (not necessary but if needed extra context)

Community
  • 1
  • 1
parliament
  • 21,544
  • 38
  • 148
  • 238
  • 1
    Keep a property `type` and keep a classname string in it. – Neel Basu Apr 03 '13 at 05:03
  • Thanks, this is what I'll do as a temp workaround but this is problematic because it will not support inheritance. That is, unless I keep a delimited list of the entire inheritance chain for each type but this becomes hard to maintain especially because my C# classes are converted to TS interfaces and as such the values assigned to properties will be dropped during the conversion. – parliament Apr 03 '13 at 19:53
  • first, yes thats how it is. second, if your core data model has deep nested inheritance relations, that is the root of the problem. do not use inheritance or limit it. – citykid Apr 05 '13 at 11:51

1 Answers1

3

At runtime you are using plain JavaScript, so you could use this answer as it relates to plain JavaScript:

How do I get the name of an object's type in JavaScript?

Here is a TypeScript get-class-name implementation that can supply the name of the enclosing TypeScript class (the link also has a static separate version of this example).

class ShoutMyName {
    getName() { 
        var funcNameRegex = /function (.{1,})\(/;
        var anyThis = <any> this;
        var results = (funcNameRegex).exec(anyThis.constructor.toString());
        return (results && results.length > 1) ? results[1] : "";
    }
}

class Example extends ShoutMyName {
}

class AnotherClass extends ShoutMyName {
}

var x = new Example();
var y = new AnotherClass();

alert(x.getName());
alert(y.getName());

This doesn't give you data about the inheritance chain, just the class you are inspecting.

Community
  • 1
  • 1
Fenton
  • 241,084
  • 71
  • 387
  • 401
  • Thanks Steve but unfortunately I don't see how any built in JS function can possible help here as the objects returned from the server that need to be type checked are always plain JSON "Object" types. The only way I can imagine to type check such an object is to compare it against a properties schema. – parliament Apr 03 '13 at 20:01
  • 3
    In that case, why not simply add a type descriptor to the JSON object? – Fenton Apr 04 '13 at 07:54
  • Please see my response to Neel's similar suggestion above. – parliament Apr 04 '13 at 08:28
  • 1
    How about if you turn the problem around - why do you need to know the type in the UI? How could you solve that problem? – Fenton Apr 04 '13 at 11:14
  • Hmm, well if you look at the AddChartView() method in the link all the way at the bottom of OP, you'll see I need to create one of many Backbone.View derived types depending on the Backbone.Model derived type that comes in. Maybe I'm missing something obvious. – parliament Apr 04 '13 at 19:49
  • 1
    parsing the constructor as a string... who would've thought :D this works for me even without inheritance at least there's nothing to maintain. thanks for your time in solving this. – parliament Apr 16 '13 at 20:23
  • I'm just glad I finally cracked it :) – Fenton Apr 17 '13 at 08:16