• Chinese version of TypeScript Tutorial – Project introduction
  • TypeScript Tutorial Chinese version – Section 0. preface
  • TypeScript Tutorial Chinese version – Section 1. An introduction to
  • TypeScript Tutorial Chinese version – Section 2. Basic types of
  • TypeScript Tutorial Chinese version – Section 3. Control flow statement
  • TypeScript Tutorial Chinese – Section 4. function
  • TypeScript Tutorial Chinese version – Section 5. class
  • TypeScript Tutorial Chinese version – Section 6. interface
  • TypeScript Tutorial Chinese version – Section 7. High-level types
  • TypeScript Tutorial Chinese version – Section 8. The generic
  • TypeScript Tutorial Chinese version – Section 9. The module
  • Chinese version of TypeScript Tutorial – Section 10.node.js

Section 7. Advanced types

Cross type

The original address

In this tutorial, you’ll learn about cross-typing in TypeScript.

An introduction to cross-types in TypeScript

A crossover type is a new type created by combining multiple existing types with all the attributes of the existing type.

Use the & operator to represent the combination type as follows:

type typeAB = typeA & typeB;
Copy the code

TypeAB will have all the properties of typeA and typeB.

Note that joint types using the | operator, define a can save typeA or typeB type value.

let varName = typeA | typeB; // union type
Copy the code

Suppose you have three interfaces: BusinessPartner, Identity, and Contact:

interface BusinessPartner {
  name: string;
  credit: number;
}

interface Identity {
  id: number;
  name: string;
}

interface Contact {
  email: string;
  phone: string;
}
Copy the code

Two cross types are defined below:

type Employee = Identity & Contact;
type Customer = BusinessPartner & Contact;
Copy the code

The Employee class contains all the attributes in the Identity and Contact types:

type Employee = Identity & Contact;

let e: Employee = {
  id: 100.name: 'John Doe'.email: '[email protected]'.phone: '(408) - 897-5684'};Copy the code

The Customer type contains all the attributes in the BusinessPartner and Contact types:

type Customer = BusinessPartner & Contact;

let c: Customer = {
  name: 'ABC Inc.'.credit: 1000000.email: '[email protected]'.phone: '(408) - 897-5735'};Copy the code

Later, if you want to implement sales staff, you can create a new cross type that contains all the attributes of the Identity, Contact, and Business Tner interfaces:

type Employee = Identity & BusinessPartner & Contact;

let e: Employee = {
  id: 100.name: 'John Doe'.email: '[email protected]'.phone: '(408) - 897-5684'.credit: 1000};Copy the code

Note that Business Tner and Identity have the same type of name attribute, and the compiler will throw an error if they are of different types.

Type the order

The order of types in type crossing is not important, as follows:

type typeAB = typeA & typeB;
type typeBA = typeB & typeA;
Copy the code

In this case, typeAB and typeBA have the same properties and are equivalent.

summary

  • A crossover type can combine two or more types to create a new type with attributes of all types;
  • The order of types in a type crossing is not important.

Type of protection

The original address

In this tutorial, you’ll learn about TypeScript type protection.

Conditional code blocks are used to limit the scope of variable types to achieve type protection.

typeof

Consider the following example:

type alphanumeric = string | number;

function add(a: alphanumeric, b: alphanumeric) {
  if (typeof a === 'number' && typeof b === 'number') {
    return a + b;
  }

  if (typeof a === 'string' && typeof b === 'string') {
    return a.concat(b);
  }

  throw new Error(
    'Invalid arguments. Both arguments must be either numbers or strings.',); }Copy the code

Here’s how it works:

  • First of all, we definealphanumericType, which can be savedString typeorNumeric typesThe value of the;
  • Next, we defineadd()Function, which sets the type toalphanumericabAdd the values of the variables;
  • Then use thetypeofThe operator checks whether both parameters are of typenumberType, if so, is used+Operator evaluates the sum of parameter values;
  • And then usetypeofThe operator checks whether both parameters are of typestringType, if so, concatenates two string parameter values;
  • Finally, an error message is thrown if both arguments are not numeric or string types.

In this example, TypeScript knows how to use typeof operators in conditional code blocks.

In the following if statement, TypeScript considers both a and B variables to be numeric:

if (typeof a === 'number' && typeof b === 'number') {
  return a + b;
}
Copy the code

Similarly, TypeScript treats the A and B variables as strings in the following if statement, so you can concatenate them into a string:

if (typeof a === 'string' && typeof b === 'string') {
  return a.concat(b);
}
Copy the code

instanceof

Like the Typeof operator, TypeScript knows how to use the Instanceof operator, as shown below:

class Customer {
  isCreditAllowed(): boolean {
    // ...
    return true; }}class Supplier {
  isInShortList(): boolean {
    // ...
    return true; }}type BusinessPartner = Customer | Supplier;

function signContract(partner: BusinessPartner) :string {
  let message: string;
  if (partner instanceof Customer) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  }

  if (partner instanceof Supplier) {
    message = partner.isInShortList()
      ? 'Sign a new contract the supplier'
      : 'Need to evaluate further';
  }

  return message;
}
Copy the code

How does it work:

  • First of all, it’s declaredCustomerSupplierTwo classes;
  • Second, create the type alias asBusinessPartnerType, which isCustomerSupplierThe union type of;
  • Third, definitionsignContract()Function that accepts a function of typeBusinessPartnerThe parameters;
  • Finally, checkpartnerWhether it isCustomerorSupplierClass, and then perform the corresponding logical processing.

In the following if block, TypeScript knows from the instanceof operator that a partner is an instanceof type Customer:

if (partner instanceof Customer) {
  message = partner.isCreditAllowed()
    ? 'Sign a new contract with the customer'
    : 'Credit issue';
}
Copy the code

In the same way, in the following if block, TypeScript knows that partner is an instance of the Supplier type:

if (partner instanceof Supplier) {
  message = partner.isInShortList()
    ? 'Sign a new contract with the supplier'
    : 'Need to evaluate further';
}
Copy the code

When an if statement qualifies one type, TypeScript knows that the else statement is of another type, as shown below:

function signContract(partner: BusinessPartner) :string {
  let message: string;
  if (partner instanceof Customer) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  } else {
    // must be Supplier
    message = partner.isInShortList()
      ? 'Sign a new contract with the supplier'
      : 'Need to evaluate further';
  }
  return message;
}
Copy the code

in

The in operator performs security checks by determining whether an attribute exists on an object, and can also be used as type protection, as follows:

function signContract(partner: BusinessPartner) :string {
  let message: string;
  if ('isCreditAllowed' in partner) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  } else {
    // must be Supplier
    message = partner.isInShortList()
      ? 'Sign a new contract the supplier '
      : 'Need to evaluate further';
  }
  return message;
}
Copy the code

User-defined type protection

User-defined type protection allows you to define type protection when using functions or helps TypeScript infer types. The user-defined type protection function is a function that returns an ARG is aType determination, as follows:

function isCustomer(partner: any) :partner is Customer {
  return partner instanceof Customer;
}
Copy the code

In this example, isCustomer() is a user-defined type protection function that can be used as follows:

function signContract(partner: BusinessPartner) :string {
  let message: string;
  if (isCustomer(partner)) {
    message = partner.isCreditAllowed()
      ? 'Sign a new contract with the customer'
      : 'Credit issue';
  } else {
    message = partner.isInShortList()
      ? 'Sign a new contract with the supplier'
      : 'Need to evaluate further';
  }

  return message;
}
Copy the code

summary

  • Type protection defines the types of variables in conditional statements;
  • usetypeofinstanceofOperators implement type protection in conditional statements.

Type conversion

The original address

In this tutorial, you’ll learn about TypeScript type conversions, which allow variables to be converted from one type to another.

JavaScript has no concept of type conversions because variables are dynamically typed. While variables in TypeScript have types, type conversions allow variables to be converted from one type to another.

TypeScript uses the AS keyword or the <> operator for type conversion operations.

Use the AS keyword for type conversion

Here we use the querySelector() method to select the first input element:

let input = document.querySelector('input["type="text"]');
Copy the code

Because the document.querySelector() method returns an Element type, the following code causes a compilation error:

console.log(input.value);
Copy the code

Since the Element type does not have a value attribute, it only exists on the HTMLInputElement type. To solve this problem, you can use type conversions to convert the input variable from Element to HTMLInputElement using the keyword as, as shown below:

let input = document.querySelector('input[type="text"]') as HTMLInputElement;
Copy the code

Now, the input variable is of type HTMLInputElement, so accessing its value property will not cause any errors, and the following code will work:

console.log(input.value);
Copy the code

Another way to convert an input variable’s type from Element to HTMLInputElement is as follows:

let enteredText = (input as HTMLInputElement).value;
Copy the code

Note that the HTMLInputElement type extends from the HTMLElement type and the HTMLElement type extends from the Element type. Converting the HTMLElement type to HTMLInputElement type is called a downward conversion.

You can also do a downward conversion as follows:

let el: HTMLElement;
el = new HTMLInputElement();
Copy the code

In this case, the type of the el variable is HTMLElement. You can specify an instance of HTMLInputElement because HTMLInputElement is a subclass of HTMLElement. The syntax for converting a type from typeA to typeB is as follows:

let a: typeA;
let b = a as typeB;
Copy the code

Use the <> operator for type conversions

In addition to the AS keyword, you can use the <> operator for type conversions, as follows:

let input = <HTMLInputElement>document.querySelector('input[type="text"]');

console.log(input.value);
Copy the code

The syntax for type conversions using the <> operator is as follows:

let a: typeA;
let b = <typeB>a;
Copy the code

summary

  • Type conversions allow a variable to be converted from one type to another;
  • useasKeyword or<>Operator to perform type conversion operations.

Types of assertions

The original address

In this tutorial, you’ll learn about type assertions in TypeScript.

An introduction to type assertions in TypeScript

Type assertion enables the TypeScript compiler to treat the type of a value as a specific type, using the AS keyword:

expression as targetType;
Copy the code

Type assertion, also known as type contraction, allows you to shrink the type range of a union type. Consider the following simple function:

function getNetPrice(
  price: number,
  discount: number,
  format: boolean.) :number | string {
  let netPrice = price * (1 - discount);
  return format ? ` $${netPrice}` : netPrice;
}
Copy the code

GetNetPrice () function accepts the price, discount and the format of three parameters, and returns a joint types for the number | string values. If format is true, the getNetPrice() function returns the formatted price as a string, otherwise as a number.

The as keyword tells the compiler that the value assigned to the netPrice variable is a string:

let netPrice = getNetPrice(100.0.05.true) as string;
console.log(netPrice);
Copy the code

Output:

The $95
Copy the code

Similarly, the following example uses the as keyword to tell the compiler that the value assigned to netPrice is a number:

let netPrice = getNetPrice(100.0.05.false) as number;
console.log(netPrice);
Copy the code

Output:

95
Copy the code

Note that type assertion does not do any type conversion; it simply tells the compiler which type to apply when doing type checking.

Optional type assertion syntax

You can also use Angle bracket syntax <> for type assertion, as follows:

<targetType>value;
Copy the code

Such as:

let netPrice = <number>getNetPrice(100.0.05.false);
Copy the code

Note that you can’t use Angle brackets in libraries like React. For this reason, it’s a good idea to keep using the AS keyword when making type assertions.

summary

  • A type assertion tells the compiler to treat the type of a value as a specific type;
  • Type assertions do no conversion operations;
  • Implementations of type assertions can be usedasKeyword or Angle brackets<>Syntax.