const ua: string = req.headers['user-agent']!
Means that you create a new variable called ua
which is explicitly set to be a string type and assign a value to it. This will trigger an error if you try to assign something that's not a string to the same variable, for example const ua: string = 42
const us = <string> req.headers['user-agent']!
In this case, you are just creating a new variable called us
which has no explicit type defined for it. In this case, TypeScript will try to guess based on what you assign. For example, see this
let a = "hello"; //no type for `a` but assigning a string makes the guess to be `string`
a = 42; //error because it's not a string
TypeScript Playground
When you do an explicit type assertion using <string>
you guarantee that TS will guess the type would be string
.
Out of the two, the first one is safer, since you know you expect a string and if it's not, then you'd get a compile time error. The second approach relies on implicit type guessing which can actually be wrong on your part. This means that at compile time this will be correct only because you've overruled the compiler but won't necessarily work at runtime. Here is an example:
let a = <string> getData();
function getData(): string | number {
return 42;
}
TypeScript Playground
This will compile but it won't be correct since you've told a compiler to always expect a string where it could actually be a number (the return type is string | number
, so it could be either) and moreover, the function just returns a number anyway. So, at runtime you have no type guarantee after this. Compare with explicit typing
let a: string = getData();
function getData(): string | number {
return 42;
}
TypeScript Playground
You now correctly get a compile time error as you should handle what happens when you get a different type.
So, usually manual type assertion should be avoided. It can lead to errors that might not even be there initially but might show up later - for example the code above might have had getData
initially only return string
so at that point there was no difference between explicit and implicit typing of the variable a
. The type assertion via <string>
would have been superfluous. However, if the function then changed to return string | number
the explicit type assertion becomes unreliable.