TypeScript 5.0 Beta has been released and is available for download. You'll have to update your dependencies in your `package.json'.
"devDependencies" : {
...
"typescript" : "^5.0.0-beta"
}
const
Type Parameters
When you're inferring the object type, TypeScript will give you a general type.
type HasNames = { readonly names: string[] };
function getNamesExactly<T extends HasNames>(arg: T): T["names"] {
return arg.names;
}
// Inferred type: string[]
const names = getNamesExactly({names: ["Alice", "Bob", "Eve"]});
but now you can add a const
modifier to a type parameter declaration to cause const
-like inference to be the
default.
type HasNames = { names: readonly string[] };
function getNamesExactly<const T extends HasNames>(arg: T): T["names"] {
// ^^^^^
return arg.names;
}
// Inferred type: readonly ["Alice", "Bob", "Eve"]
// Note: Didn't need to write 'as const' here
const names = getNamesExactly({ names: ["Alice", "Bob", "Eve"] });
Decorators
One of the most interesting additions for me is Decorators. These are an upcoming ECMAScript feature that allows the customisation of classes and members in a reusable way.
export class ProductService {
public getProducts() {
return fetch('/api/getProducts');
};
}
If we wanted to trace this in development we could start adding in logger calls or the really dirty console.log()
method. But with decorators we can create a decorator to wrap methods with the extra functionality.
function log(originalMethod: any, _context: any) {
function replacementMethod(this: any, ...args: any[]) {
console.log("LOG: Entering method.")
const result = originalMethod.call(this, ...args);
console.log("LOG: Exiting method.")
return result;
}
return replacementMethod;
}
export class ProductService {
@log
public getProducts() {
return fetch('/api/getProducts');
};
}
So when we are now working in our project, we can flag a method with the decorator without added piles of extra code that you might want to remove later, or just making the code less readable. You can go further with this by extending the decorator further to match what you are trying to do.
Enums
Enums have been something that I find quite helpful in TypeScript. In TypeScript 5.0 there are now some improvements to
how enums can be used. Previously you could pass thing in to an enum argument and TypeScript wouldn't raise an error.
Now you will be a warning represented as you pass it in. However, I'd still use LogLevel.DEBUG
instead of 0
.
enum LogLevel {
DEBUG,
ERROR,
WARNING,
}
const log = (level: LogLevel, message: string) => {
};
// Valid
log(2, "Error message");
log(LogLevel.WARNING, "Warning message");
// Invalid
log(1234, 'Invalid message')
Speed, Memory, and Package Size Optimisations
Taken straight from Microsoft's own blog, here are the improvements for installing and running TypeScript:
Scenario | Time or Size Relative to TS 4.9 |
---|---|
material-ui build time | 90% |
Playwright build time | 89% |
tsc startup time | 89% |
tsc build time | 86% |
Outlook Web build time | 83% |
VS Code build time | 81% |
typescript Package Size | 58% |
Microsoft are keeping quiet on how they made these improvements, but it's also mentioned that they've moved from namespaces to modules, probably inline with ESM plans. This would be extra useful with using Microsoft's Monaco package which had issues related to namespacing vs ESM.
Also, the TypeScript package is about 33% smaller now. This comes with some slim-lining some object types and adding uniformity.
This is all exciting to see, but it's still in Beta, so maybe roll back that beta dependency and wait on what Microsoft are going to hand out in the general release!