TypeScript Casting Gotchas

Below are two TypeScript “gotchas” that I have come across while writing my first TypeScript app.

1) Here we are creating an instance of the customer class and calling a method to write some data to the console.
Then the object is turned into JSON and then parsed and cast as a customer class. There is no TypeScript compile time error, but there is a runtime error:

class Customer {
    constructor(public name: string) {
    }
    showInfo() {
        console.log('time:' + new Date().getMilliseconds() + ' name:' + this.name);
    }
}

window.onload = () => {
    var customer = new Customer('russ');
    customer.showInfo();

    var customerJSON = JSON.stringify(customer);
    var customerCasted = <Customer>JSON.parse(customerJSON);
    customerCasted.showInfo();//RUNTIME ERROR
}

vs-javascript-exception

Visual Studio will let us compile and run this code without an error so why isn’t there a showInfo method on our parsed Customer class?
Because TypeScript is still just JavaScript.  There is no magic at runtime, the castedCustomer object is an anonymous object with no specific object definition.

Once this is realized you can then change the code and instantiate a new customer which will of course then be of type Customer and have the correct showInfo method.

window.onload = () => {
    var customer = new Customer('russ');
    customer.showInfo();

    var customerJSON = JSON.stringify(customer);
    var customerCasted = <Customer>JSON.parse(customerJSON);
    //customerCasted.showInfo();//RUNTIME ERROR

    var fixedCustomer = new Customer(customerCasted.name);
    fixedCustomer.showInfo();
}

2) Another one is casting an object to another type which it is not related by interface or inheritance.

class Dog {
    constructor(public name: string, public nickName: string) {
    }
}
class Cat {
    constructor(public name: string) {
    }
}
class Dinosaur {
    constructor(public dinoName: string) {
    }
}

window.onload = () => {
    var dog = new Dog('spot', 'doggy');
    var cat = new Cat('furball');
    var dino = new Dinosaur('rex');

    var dogB = <Dog>cat;//OK
    var dogC = <Dog>dino;//COMPILE ERROR

    var catB = <Cat>dog;//OK
    var catC = <Cat>dino;//COMPILE ERROR

    var dinoB = <Dinosaur>cat;//COMPILE ERROR
    var dinoC = <Dinosaur>dog;//COMPILE ERROR
}

typescript-compilation-errors

The Dog class and Cat class share part of the same typed definition(name: string). Because of this they are convertible as far as TypeScript is concerned instead of producing a compile time error. Although the Dinosaur class only has one string property it cannot be casted to or from because the property-name is different.

One thought on “TypeScript Casting Gotchas

  1. This is partly why they’re not called “casts” in TypeScript. They call them “type assertions”, to make it clear that they merely represent a strongly-held belief of the coder and don’t have any effect at runtime. (Ironically they are more like casts in the C language).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s