DEV Community

Discussion on: Type `Assertions` vs `Declarations` - the dangers of `as` in Typescript

Collapse
 
shakyshane profile image
Shane Osbourne

There's no 'inheritance' involved in this approach, Typescript has good support for tagged/discriminated unions - it's only the addition of 'as' here that causes problems.

This style is often used by devs familiar with similar things in other languages, like in Rust, it would be

enum Msg { 
  SignIn { email: String, password: String },
  SignOut
}
Collapse
 
jwp profile image
John Peters • Edited

You're right, I used the term inheritance; incorrectly to describe a pattern based on the single strong type. It is a type at layer zero, which could be either inherited or contained.

If we define something to be more than one type, and we don't use a containment pattern then, we are propelled to use the typescript multi-type system, which you show here.

When we use a field within an object to describe the type, we still achieve polymorphism, but we have the potential to run into issues as you describe here. I've seen this mistake happen over in older JavaScript code, where the freedom of creating objects, anywhere, anytime, anyplace causes issues because of missed properties, property key's being misspelled in some of the objects, expecting functions that aren't there; and the issues with not following a type system. This is why I prefer strong types and the containment pattern like this:


Msg {
   logIn:SignIn     //from the enum or other strong type
   logOut:SignIn  // from the enum or other strong type

The problem of accidental type confusion is resolved because both logIn and logOut are typed. Any attempt to sidestep the type constraint is immediately caught at code time. But here, we would need a discriminator as we have both types contained and we are easily able to determine their state.

 if(Msg.Login){ post(Msg.Login)}
 if(Msg.Logout){ post{Msg.Logout)}

I see the 'as' operator to be a casting mechanism. When it's used with non-strongly typed code, then the issue you describe is more than just a typescript error, it's how JavaScript has been operating with the loosely typed system for 20 years now.

I did gain more insight from your article on the newer polymorpic behaviors that Typescript is now support. Thanks I'll look into it more.