Alwaysblue
Alwaysblue

Reputation: 11950

Understanding type asseration

I am just starting with typescript and as much as i thought things are going to be easy, typescript doesn't seem to be that similar to javascript and kinda confusing

Anyway, In typescript (Not sure if my code is valid or not) what is the difference between doing something like this

    const ua: string = req.headers['user-agent']!

or as per this answer something like this: https://stackoverflow.com/a/38831495/10433835

const us = <string> req.headers['user-agent']!

Ps: I am not sure which of the code is valid.

Upvotes: 1

Views: 92

Answers (3)

VLAZ
VLAZ

Reputation: 29116

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.

Upvotes: 3

hackape
hackape

Reputation: 20007

Both expressions are valid. But they mean different intention.

case 1:

const ua: string = req.headers['user-agent']!
  1. you declare a variable ua and mark it as string type
  2. you assign a value to it
  3. typescript will check if the value is good to be assign to that variable.

case 2:

const ua = <string>req.headers['user-agent']!
  1. you declare a variable ua without specifying its type
  2. you assign to it a value, which you manually type-asserted as string type
  3. typescript will check:
    • if your type assertion is applicable to that value
    • if above is good, then it'll infer the type of ua from this assignment

Upvotes: 1

Kirill Morozov
Kirill Morozov

Reputation: 603

Well i mean the difference is that in the first example you are declaring constant of type string and assign it the value of the 'user-agent' of headers of req.

In the second one you are declaring constant type any and assign it explicitly casted to type string value of the 'user-agent' of headers of req.

I am not sure if i answered your question, if not please provide more context. Both code samples are "valid".

Upvotes: 1

Related Questions