The TypeScript language builds on JavaScript by adding syntax for type declarations and annotations. TypeScript uses static type-checking which provides ahead-of-time (AOT) compilation to help us identify errors before we run our code.
TypeScript is an open-source language with a huge developer community that continues to update its features, in a sequence of releases, making developer life easier. We’ll look into what the latest release, 4.1, has to offer. We’ll also explore the 4.2 beta release notes, which tease some new features for upcoming releases, and the future release roadmap.
Typescript 4.1 Release Features
Microsoft released TypeScript 4.1, the current version, in November 2020, roughly three months after 4.0. To install TypeScript via npm, so we can explore its features, use this command:
Now, let’s take a look at what 4.1 offers.
Template Literal Types
String literal types in TypeScript enable us to model functions and APIs that expect a set of specific strings. Template literals were added to JavaScript back in ES2015. They provide a convenient and readable way to insert values into strings. These strings are delimited by backticks that evaluate any expression surrounded by the following, inserting the result into the string.
TypeScript 4.1 lets you use the template literal syntax in types as well as values. This means, if your type represents a single string literal — or, more likely, a union of multiple string literals — you can use a template literal type to create a new string literal type derived from the old one.
As the example above shows, the transformation is distributed over the union, applied to each member separately, then produces a union of the results. If you include multiple union types in the template literal, it produces every combination.
Template literal types are helpful for correcting programmers’ mistakes right at the time of compilation. For example, if you mistakenly misspelled a word, it throws a compile-time error or shows suggestions to correct it before you run.
As you can see, this is useful for building out patterns of string types. It can also be useful when combined with other type operators such as keyof.
Capitalize is one of the four TypeScript 4.1 helper types that adjust capitalization of the string’s starting character. These types are:
- Capitalize
- Uncapitalize
- Uppercase
- Lowercase
Key Remapping in Mapped Types
Mapped types can be combined with template literal types. Think about generating a type for accessors using the previous example:
This creates a new type, with the original data members mapped to a function returning their type:
Now, we need to map keys of the type to:
We could do this simply as:
But, we need to retain the original K, so we access PersonDataAccessors (K). Remapping with as allows us to map the left-hand side while still accessing the original key:
This, in turn, creates the type:
Recursive Conditional Types
TypeScript’s type system cannot flatten and build up container types at arbitrary levels, like JavaScript’s .then method on Promise instances (where it unwraps each promise until it finds a value that’s not “promise-like” and passes that value to the callback).
TypeScript 4.1 eases some restrictions on conditional types so they can model these patterns. In TypeScript 4.1, conditional types can now immediately reference themselves within their branches, making it easier to write recursive type aliases.
For example, if we want to write a type to get the element types of nested arrays, we can write the following deepFlatten type.
Similarly, in TypeScript 4.1 we can write an Awaited type to deeply unwrap Promises.
Use these recursive types responsibly on resource-intensive executions as they can hit an internal recursion depth limit on complex inputs. When they hit that recursion limit, it triggers a compile-time error. In general, it’s better not to use these types than to write code that fails on more realistic examples.
Checked Indexed Accesses (--noUncheckedIndexedAccess)
Index signatures in TypeScript enable you to access arbitrarily-named properties, as demonstrated in the following Options interface. Here, we see that an accessed property that does not have the name path or the name permissions should have the type string | number:
A new flag, --noUncheckedIndexedAccess, provides a node where every property access (like opts.path) or indexed access (like opts "blabla") is considered potentially undefined. That means that if you need to access a property, like opts.path in the last example, you must check for its existence or use a non-null assertion operator (the postfix ! character):
This flag can be handy for catching out-of-bounds errors, but it might be noisy for a lot of code, so it is not automatically enabled by the --strict flag. However, if this feature is interesting to you, you should try it and determine if it makes sense for your team’s codebase.
TypeScript 4.2 Beta
TypeScript released its 4.2 beta version in January 2021. To install the latest TypeScript beta version, so you can check out its new features, use the command:
Let’s see what’s in store for TypeScript 4.2 beta.
Leading and Middle Rest Elements in Tuple Types
In previous versions of TypeScript, we could not write rest elements anywhere in tuple type except at the last position.
TypeScript 4.2 allows rest elements anywhere within a tuple with only a few restrictions. For example, you can place a rest element anywhere in a tuple, so long as it’s not followed by another optional element or rest element. In other words, only one rest element per tuple, and no optional elements after rest elements.
Smarter Type Alias Preservation
In earlier versions, we were not able to see the declared type when we created a method with primitive types. For example, for the code below, when we hover over the doStuff function, we expect to see the type ‘BasicPrimitive | undefined’.
But, instead, we see the type as:
This is changed in TypeScript 4.2 to show what we'd expect:
Stricter Checks for the in Operator
In JavaScript, using a non-object type on the right side of the in operator triggers a runtime error. TypeScript 4.2 catches this error at design time.
TypeScript makes it possible to use “dotted” property access syntax, like user.name, when a type has a string index signature.
You can use the flag --noPropertyAccessFromIndexSignature to shift to TypeScript’s older behavior that issues an error.
noImplicitAny Errors Apply to Loose yield Expressions
When a yield expression is captured, but isn’t contextually typed (that is, TypeScript can’t figure out what the type is), TypeScript now issues an implicit any error.
TypeScript’s lift Callback in visitNode Uses a Different Type
TypeScript’s visitNode function takes a lift function. lift now expects a readonly Node instead of a NodeArray Node. This is considered an API-breaking change, and you can read more about it on GitHub.
Roadmap and Future Development Plans for TypeScript 4.3
In addition to the features discussed for 4.3 beta, TypeScript also teased its possible upcoming features in their official roadmap. Let’s look at some of the notable features.
typeof class Changes
typeof should allow users to describe types with class-specific characteristics. For example, take a look at the below class declaration.
This is an awkward static and instance pattern that users need to write on anonymous object types and interface types. Instead, you can modify this, using typeof:
Allow More Code Before super Calls in Subclasses
The proposed change relaxes the rule that super call must be the first statement within the subclass constructor. It allows something like the code below without throwing any errors.
More possible TypeScript 4.3 features include:
- Generalized index signatures
- --noImplicitOverride and the override keyword
- static Index Signatures
- Use unknown as the type for catch clause variables
Microsoft might still update these features as developers report more issues or submit more feature requests.
Beyond 4.3
TypeScript’s awesome open-source community is constantly updating it with new features. If you are a developer working with TypeScript and come across something you think can be better, you can start contributing bug fixes and new features to their GitHub page. The community might add them to forthcoming releases, or you can add them as a pull request.
The TypeScript roadmap also teases some possible features and investigations beyond version 4.3:
- Investigate nominal typing support
- Flatten declarations
- Implement the ES decorator proposal
- Investigate ambient, deprecated, and conditional decorators
- Investigate partial type argument inference
- Implement a quick fix to scaffold local @types packages
- Investigate error messages in haiku or iambic pentameter
- Implement decorators for function expressions and arrow functions
GrapeCity supports TypeScript in widgets such as SpreadJS. To learn more about how GrapeCity’s developer tools help you save time while incorporating spreadsheets, presentations, user interface controls, and other handy tools into your app, visit GrapeCity.com today.