Is there any difference between
const b = 'test' as string;
and
const b: string = 'test';
Simple answer Yes.
Explanation
( replacing const with let )
let b: string = 'test' we are explicitly saying we want b to be a string, so assigning anything other than a string to b will be a type error.
let foo = 'hello' as string
Using as is called type assertion, we are telling typescript that , we want foo to be this particular type
( for the example you gave, they basically do the same thing ), but the type assertion can also be used in a situation like this
interface User {
name: string;
age: number;
occupation: Array<string>
}
// doing this will cause an error because the {} object does not
// satisfy the contract defined in the User Interface (structurally)
let currentUser: User = {};
// in this case what we will do is use type assertion (typescript still does type checking as well
let currentUser: User = {} as User;
From your example, the both code do the same thing, but type assertion and explicitly specifying the type of a variable are different
The difference is, normally with assignment the value being assigned must extend the type. But when using the as operator, either the value's type can extend the variable's type, or vice versa. Consider the following code:
type Foo = {
foo: string;
}
let bar = {
bar: 42
}
type Bar = typeof bar;
let foobar = {
foo: 'hi',
bar: 42
}
Note that types Foo and Bar are not compatible with each other. However, foobar is both a Foo and a Bar:
let foo: Foo;
foo = foobar; // ok, typeof foobar extends Foo
foo = {} as Foo; // ok. Foo extends {}
foo = bar as Foo; // fails, neither Foo nor Bar extends the other
bar = foobar; // ok, foobar extends Bar
foo = foobar; // similarly
foobar = bar; // fails, Bar doesn't extend typeof foobar
One of contexts where this makes a difference is the following (which passes type checking):
export default {bar: 0, whoops: 'invalid'} as Bar;
Although you do get intellisense when creating that object, you can still create properties that shouldn't be there. So a "workaround" which flags the type error is:
const bar: Bar = {bar: 0, whoops: 'invalid'};
export default bar;
In more recent versions of TypeScript, the satisfies keyword was introduced. It is preferred in code like:
let foo = {} satisfies Foo; // Fails as expected
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With