TypeScript is a superset of JavaScript, if one avoids certain features. Under the hood, transpiling TypeScript to JavaScript is simply removing the type annotations. In other words, the actual running code isn’t anymore powerful than JavaScript itself.
Additionally, TypeScript doesn’t offer simpler syntax than JavaScript. TypeScript code strictly longer than JavaScript code. What is the point of TypeScript if it does not provide more capabilities at runtime and the code is longer?
Types allow us to write more precise code to detect errors before running it. Ultimately we still need to unit test all our code as unit tests are exercising JavaScript, not TypeScript.
Type are like unit tests as errors indicate something is wrong with the implementation. With a properly configured editor and sound types, one can detect bugs as the keys are pressed. This is why developers are so excited to use typed languages.
Types are mainly inferred by TypeScript but they can also be declared. The inferred types are usually good enough but declaring types gives us an opportunity to name things.
inferredThing
doesn’t have a declared type and TypeScript infers the type to be { name: string; }
. Note the inferred type is in the error message.
But by creating the type alias Person
, we get a more obvious error message.
Relying on inferred types with judicious type aliases will get one really far with TypeScript. However, at some point one will run into a non-obvious type error. The first inclination might be to reach for type assertions to make the problem go away, but typically that would only make the problem worse. Type assertions are the last resort for those who truly know better than the TypeScript compiler. Remember types are not for runtime correctness, types are for us developers as we are writing the code. A bad type assertion will ruin the very protection we desire from types.
Instead of type assertions, one will likely need to use advanced features of TypeScript to retain type soundness. These features are dedicated towards towards maintaining the types we already have. A few quick examples on what TypeScript is capable of,
{name: string} | {age: number}
is the type of either an object of {name: string}
or an object of {age: number}
, but not an object with both fields nor an empty object.{name: string} & {age: number}
is the same as the type {name: string, age: number}
.Promise<T>
to T
. Also used to retain inferred array types{name: 'Alice' | 'Bob'}
to {Bob: boolean}
. Also used to retain inferred object typesAre we your type? You’re in luck, Battlefy is hiring.