Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dates in a Typescript interface are actually strings when inspected

Unfortunately the total code to reproduce this would be extensive, so I'm hoping that my problem is obvious with what I can easily provide. If required, I'll post a more complete solution.

First, I am defining an interface:

export interface ITest {
    myDate: Date;
}

Then I create an array of these for testing:

export const TEST: ITest[]=[{myDate: new Date(1995, 8, 1)}]

I expose these using a service in Angular2 that is hitting the InMemoryDbService from angular2-in-memory-web-api. The code where I call this and get the array is as follows:

get(): Promise<ITest[]>{
    return this.http.get(this.testUrl)
        .toPromise()
        .then(response => response.json().data as ITest[])
        .catch(this.handleError);
}

...and then I bring it into my component with:

    this.testService.get().then(tests => {
        this.tests = tests;
        console.log("Date Type:"+typeof(this.tests[0].myDate));
    });

This all works fine, but the problem is the console.log statement shown there results in:

Date Type:string

The data in it is correct, in that the string held by my date is 1995-09-01T07:00:00.000Z, but the main issue is - it isn't a Date it is a string! In VS Code I even get code completion for methods like toDateString but when I execute them I (of course) get toDateString is not a function.

I am pretty sure that the issue is occurring with response => response.json().data as ITest[], but why isn't the date data being cast to an actual Date? I'm doing it wrong, that I understand. How should I be handling this such that I can have my objects obtain the types I expect?

like image 263
WillyC Avatar asked Oct 07 '16 21:10

WillyC


1 Answers

You are using an interface and type assertion to basically tell TypeScript that the object conforms to that interface.

But this is not actually the case as what you are casting is a json object in which the "myDate" property is being represented as a string.

Using type-assertion does not affect generated javascript code in any way - you have to do the actual type conversion yourself.

The reason why it comes as string is that there is no type defined in JSON format to represent Date, so the server in all likelihood is just sending a result of date.toString().

One option for you would be to have a class for representing the returned value and instantiate an object from the JSON properties like so:

var response = JSON.parse(JSON.stringify({ myDate: new Date() }));

class Test  {
    constructor(json: { myDate: string }) {

        this.myDate = new Date(json.myDate);
    }

    myDate: Date;
}

let test = new Test(response);
console.log("Type: " + typeof (test.myDate));
console.log("Value: " + test.myDate);
like image 199
Fredy Treboux Avatar answered Sep 25 '22 14:09

Fredy Treboux