-1

I ran into a bug today that caused me a lot of digging around and confusion. It was all caused by my assumption that when a property in a TypeScript class is defined as string, TypeScript will either throw an error or convert another type to a string representation.

I would expect the following to either throw an error in class construction or that the argument is converted to a string.

class A { 

    constructor(public str: string) { 
        console.log(typeof (str));
        console.log(typeof (this.str));
    }

    t() { 
        return typeof (this.str);
    }
}

const a: A = new A(5 as any);
const t = a.t();

// t is now 'number'!!!!

Playground link

When looking at the generated JavaScript it seems obvious it is what should happen but I think TypeScript would be more robust and this functionality would be by design.

Why does TypeScript not convert my number type to a string?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
span
  • 5,405
  • 9
  • 57
  • 115
  • Because TypeScript *doesn't exist* at runtime? It's unclear why you made those assumptions, but they're wrong; TS does *compile time* type checking. – jonrsharpe Jun 13 '19 at 21:28
  • So if types can't be trusted in TypeScipt what is the point? A bit harsh dude. – span Jun 13 '19 at 21:29
  • They're trustworthy if used correctly and with some understanding of what's happening, but they aren't magical. TS types alone do not cause type errors or conversion at runtime, and using assertions like `as any` limit their usefulness at compile time. – jonrsharpe Jun 13 '19 at 21:33
  • Why *would* one be? It's outside TS's goals to generate additional runtime type checking/casting code, and you can see from the transpiled JS that none exists. Again, TS is a *compile time* type checking tool. – jonrsharpe Jun 13 '19 at 21:40
  • 2
    @span TypeScript is just a compile-time type checker. This is a fundamental design choice of the language (which effectively makes it "just JavaScript" with better auth-time features). You are basically asking questions covered by the TS FAQ: https://github.com/Microsoft/TypeScript/wiki/FAQ – Aaron Beall Jun 13 '19 at 21:41
  • There's an issue in TypeScript github, describing a similar problem: [Type conversion doesn't actually perform conversion](https://github.com/microsoft/TypeScript/issues/31229). The issue is closed, the resolution seems to be "it's in the FAQ". – artem Jun 13 '19 at 21:41
  • And as you probably noticed casting to `any` bypasses the compile time type checks, as is also by design. If you didn’t do that you would get an error. – Sami Kuhmonen Jun 13 '19 at 21:45
  • Potential duplicate https://stackoverflow.com/questions/43373144/why-does-typescript-allow-to-assign-an-any-object-type-to-class-object – ProdigySim Jun 13 '19 at 22:34
  • Thanks for your replies. This is just a quick sample to ask why TypeScript does not either convert the values or throw an error so I don't want to get hooked up on `any` or `as`. The "real world" issue I had was that I was reading data from a `.json` file and mapping it to a TypeScript class. The data in the file was a `number` and the TypeScript class a `string`. I, naïvely expected TypeScript to throw an error if it could not convert the value but since it is only compile time checking I can see why not. – span Jun 15 '19 at 14:54

1 Answers1

0

Casting variables with as should be considered dangerous. This is a Type Assertion--you are telling the Typescript compiler that you know better than it what the type of the object is. If you lie to the Typescript compiler, it can't help you keep your program safe.

To make matters worse, you are using the any type here, which is a very permissive type. If you cast to any other type, including {}, you would have gotten a compiler error. However any can be assigned to any type without error.

ProdigySim
  • 2,825
  • 1
  • 21
  • 17