7 useful new TypeScript features

7 useful new TypeScript features

1. Optional Chaining

Available from v3.7

This is a pain point when you are trying to access nested data, and the more nested the data is, the more cumbersome the code becomes.

In the following example, to access address, you must traverse data.customer.address, and data or customer may be undefined, so it is common to use the && operator or similar techniques in the example to traverse each level of definition.

Now you can use the .? operator to selectively access data. This way, if there is a parent object that has not been defined yet, undefined will be returned anywhere in the chain instead of crashing at runtime.

// Before v3.7 if (data && data.customer && data.customer.address) {
   const {address} = data.customer
   const fullAddress = `${address.street}, ${address.city}, ${address.state }${address.zipcode}`
}

// v3.7

// data access
const address = data?.customer?.address
const fullAddress = `${address?.street}, ${address?.city}, ${address?.state } ${address?.zipcode}`

// Also applies to the array customers?.[0]?.['address']

// Check if the method is defined and call customer.approve?.()

2. Null value coalescing

Available from v3.7

The null coalescing operator is an alternative to || that returns the expression on the right if the left is null or undefined. How is this different from ||? || is essentially the Boolean OR operator in JavaScript, and we try to exploit short-circuiting to return the first non-false value. This may produce unexpected results because the number 0 or the empty string will be considered false when required as valid input. Let's illustrate this with an example:

// Previously passPhrase = data.inputString || 'Unknown' // would not accept "" (empty string)
passCode = data.number || '-1111' // 0 will not be accepted 
rememberMe = data.rememberFlag || true // will always be true!!!


// Now passPhrase = data.inputString ?? 'Unknown' // is Unknown only if inputString is undefined
passCode = data.number ?? '-1111' // 0 can be passed rememberMe = data.rememberFlag ?? true // false is a valid value

This way, you can clearly distinguish between undefined and false values.

3. Recursive type aliases

Available from v3.7

Many data types in the real world are recursive. For example, when you try to process hierarchical data, you will find that there are repeated patterns of the same type of data. jsON is a good example, it is essentially a hash map, and a hash map itself can contain another map or an array of maps.

Before v3.6, if you had to define a simple jsON type, you had to do it like this:

interface JSONObject { [x: string]: JSONValue; }
interface JSONArray extends Array<JSONValue> { }
type JSONValue = string | number | boolean | JSONObject | JSONArray

If you try to inline the types in lines 1 and 2 like in line 3, you will probably get the following error: Type alias JSONValue circularly references itself.

This problem has been effectively solved in v3.7, and can be simply coded as follows:

type JSONValue = string | number | boolean | { [x: string]: JSONValue } | Array<JSONValue>

4. Assertion Signature

Available from v3.7

You should know that TypeScript has type guards that play nicely with the typeof and instanceOf operators in JavaScript. This is useful for adding preconditions to a function's arguments in order to restrict them to specific types.

Let's write a code that uses all of the above, by adding type guards to ensure that the given input is a date, and extract the year from it:

function isDate(input: unknown) : asserts input is Date { 
  if (input instanceof Date) 
    return; 
  else 
    throw new Error('Input must be a Date!'); 
} 

function getYear(input: unknown) : number { 
  isDate(input); 
  return input.getFullYear() // TypeScripts knows that input is Date 
} 


console.log(getYear(new Date('2019-01-01'))); 
console.log(getYear('2019-01-01'));

The above code looks fine, but TypeScript still complains that getFullYear is not available on an unknown type.

Starting from v3.7, TypeScript adds a new keyword called asserts, which enables the compiler to know the correct type from the assertion. For assertion functions, you should add asserts <param> as <type> instead of the return type.

This way, if the assertion passes, TypeScript will assume that the parameter is of the type defined earlier. The modified code is as follows:

function isDate(input: unknown) : asserts input is Date { 
  if (input instanceof Date) 
    return; 
  else 
    throw new Error('Input must be a Date!'); 
} 

function getYear(input: unknown) : number { 
  isDate(input); 
  return input.getFullYear() // TypeScripts knows that input is Date 
} 


console.log(getYear(new Date('2019-01-01'))); 
console.log(getYear('2019-01-01'));

5. Provide better feedback for Promises

Improvements since 3.6

It is a common mistake to use Promise directly in your code and forget to use await or then, as shown below:

interface Customer {
    name: string
    phone: string
}

declare function getCustomerData(id: string): Promise<Customer>;
declare function payCustomer(customer: Customer): void;

async function f() {
    const customer = getCustomerData('c1')
    payCustomer(customer)
}

Previously TypeScript had no idea about Promises and displayed an error message that had nothing to do with them, like this:

Starting with v3.6, the compiler is smart enough to suggest promises that you should fulfill. Note how the latest compiler handles the same error:

Let's briefly discuss some of the features without going into too much detail:

6. Unicode Identifiers

Available since v3.6

const hello = "world"

The above code may not compile on earlier versions of TypeScript, but now you can define identifiers from a wider set of unicodes.

7. Incremental Compilation

Available since v3.4

If you're using TypeScript on a large project, it can take a long time for the compiler to respond to changes you make to files in that project. There is now a new --incremental flag that you can add to the tsc (typescript compiler) command line which will incrementally compile modified files.

TypeScript does this by storing information about your project since the last compilation in a local cache directory within your codebase. On React codebases, always remember to configure Webpack or Parcel correctly to take advantage of incremental compilation in your build pipeline.

The above are the details of 7 useful new TypeScript features. For more information about new TypeScript features, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • How to explain TypeScript generics in a simple way
  • TypeScript generic parameter default types and new strict compilation option
  • Detailed explanation of type protection in TypeScript
  • Summary of the use of TypeScript in React projects
  • TypeScript Magic Hall: A Super Practical Manual on Enumerations
  • TypeScript Advanced Types You Don’t Know (Summary)
  • Detailed steps for typescript configuration alias
  • A brief analysis of TypeScript namespace
  • Detailed explanation of TypeScript 2.0 marked union types

<<:  Share 8 MySQL pitfalls that you have to mention

>>:  Detailed explanation of Nginx log customization and enabling log buffer

Recommend

js canvas implements verification code and obtains verification code function

This article example shares the specific code of ...

MySQL establishes efficient index example analysis

This article uses examples to describe how to cre...

Tkinter uses js canvas to achieve gradient color

Table of contents 1. Use RGB to represent color 2...

MySQL master-slave replication configuration process

Main library configuration 1. Configure mysql vim...

How to use Linux whatis command

01. Command Overview The whatis command searches ...

Web design tips on form input boxes

1. Dashed box when cancel button is pressed <br...

Data Structure - Tree (III): Multi-way Search Tree B-tree, B+ tree

Multi-way search tree Height of a complete binary...

Detailed explanation of using split command to split Linux files

A few simple Linux commands let you split and rea...

Vue conditional rendering v-if and v-show

Table of contents 1. v-if 2. Use v-if on <temp...

Vue+flask realizes video synthesis function (drag and drop upload)

Table of contents We have written about drag and ...

SQL statements in Mysql do not use indexes

MySQL query not using index aggregation As we all...

How to understand the difference between ref toRef and toRefs in Vue3

Table of contents 1. Basics 1.ref 2. toRef 3. toR...

MySQL 8.0.19 Installation Tutorial

Download the installation package from the offici...

Solution to MySQL startup successfully but not listening to the port

Problem Description MySQL is started successfully...