WillyC WillyC - 11 months ago 68
TypeScript Question

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
. The code where I call this and get the array is as follows:

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

...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
statement shown there results in:

Date Type:string

The data in it is correct, in that the string held by my date is
, but the main issue is - it isn't a
it is a
! In VS Code I even get code completion for methods like
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
? 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?

Answer Source

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);