TypeScript is improving every day. We keep getting new features with every release. In this article, we’ll look at the new stuff that was released with TypeScript 3.5.
New features include speed improvements to incremental builds, new Omit
helper type, better excess property checks in union types, and type inference for the composition of constructors.
Speed Improvements
With the --incremental
build mode, subsequent builds are faster because of the caching of references, file locations, and other build related data.
Omit Helper Type
The Omit
helper type was introduced in TypeScript 3.5 to let us create a new type from existing types by excluding some properties from the original.
For example, given the Person
type defined in the following code:
type Person = {
name: string;
age: number;
address: string;
};
We can create a new type without the address
property by using Omit
:
type NewPerson = Omit<Person, "address">;
Which is the same as:
type NewPerson = {
name: string;
age: number;
}
Better Excess Property Checks in Union Types
Before TypeScript 3.5, excess property checks didn’t catch properties in some cases. If we have a union type, then TypeScript versions before 3.5 allows a property with the same name as the type of a union type but with a different type than what’s specified in the type definition.
For example, if we have:
type Person = {
name: string;
age: number;
};
type Address = {
address: string;
}
const person: Person | Address = {
name: 'Joe',
age: 1,
address: true
};
We can set address
to something that’s not a string, which isn’t something that should be allowed.
This has been fixed in TypeScript 3.5. Now address
has to be a string since it’s specified to be a string.
The --allowUmdGlobalAccess
Flag
UMD global declarations files can now be referenced in TypeScript 3.5 using the new --allowUmdGlobalAccess
flag.
It adds more flexibility for mixing and matching 3rd party libraries. Now the globals that libraries declare can be consumed, even from within modules.
Smarter Union Type Checking
We would get an error with the following union type definition and variable assignment before TypeScript 3.5:
type Foo = { done: boolean, value: string }
type Bar =
| { done: false, value: string }
| { done: true, value: string };
declare let source: Foo;
declare let target: Bar;
target = source;
Before 3.5, done
would be recognized as having a literal type with the value instead of the boolean type.
Now it recognizes the type for the done
field as being boolean. This now works boolean can only be true
or false
.
Higher-Order Type Inference From Generic Constructors
When we compose generic constructors as we do in the following function:
function composeConstructors<T, U, V>(
F: new (x: T) => U, G: new (y: U) => V): (x: T) => V {
return x => new G(new F(x))
}
TypeScript 3.5 can infer the type T
, U
, and V
by inferring the chain of types that are formed from the composition.
If we have the following code:
class Foo<T> {
value: T;
constructor(value: T) {
this.value = value;
}
}
class Bar<U> {
value: U;
constructor(value: U) {
this.value = value;
}
}
let f = composeConstructors(Foo, Bar);
let a = f('foo');
Now we’ll get that a
has the type Bar<Foo<string>>
. Versions before 3.5 has the type Bar<{}>
for a
.
TypeScript 3.5 is smarter now. It can infer types formed by the composition of constructors.
With TypeScript 3.5, it’s smarter and faster. It can infer types formed by the composition of constructors by going through the chain of composition.
Excess property checks are checked for union types, which didn’t happen in earlier versions.
Also, we have the -- allowUmdGlobalAccess
flag to run access global variables from UMD modules.
Finally, we have the Omit
type for creating a new type from existing types with some properties removed.