TypeScript common types

Original link: https://www.iyouhun.com/post-230.html

TypeScript is a superset of JS, TS provides all the features of JS, with the addition: type system

JS has types (eg, number/string, etc.), but JS doesn’t check if the variable’s type has changed , while TS checks

The main advantage of TypeScript’s type system: unexpected behavior in code can be explicitly flagged, reducing the likelihood of errors

type annotation

sample code

 let age: number = 18;

In the code :number is a type annotation

A type annotation constrains that only values ​​of this type can be assigned to this variable

Error demo

 // 错误原因:将string 类型的值赋值给了number 类型的变量,类型不一致let age: number = '18';

Common base types

Commonly used basic types in TS can be divided into two categories

  1. JavaScript has types
    • Primitive types: number/string/boolean/null/undefined/symbol
    • Object type: object (array, object, function, etc.)
  2. TypeScript new types
    • Union types, custom types (type aliases), interfaces, tuples, literal types, enumerations, void, any, etc.

Note: Primitive types are written in the same way in TS and JS, and object types are more refined in TS, and each concrete object has its own type syntax

primitive type

Features: Can be written exactly as the name in JavaScript

number/string/boolean/null/undefined/symbol

 let age: number = 18; let username: string = '张三'; let isMerry: boolean = false; let unique: Symbol = Symbol('shuiruohanyu');

array type

Two ways to write an array

  1. 类型[] notation, such as

     let userList: string[] = ['John', 'Bob', 'Tony']; let peopleList: object[] = [{ name: '张三', age: 18 }];
  2. Array<type> writing, such as

     let user2List: Array<string> = ['John', 'Bob', 'Tony']; let people2List: Array<object> = [{ name: '张三', age: 18 }];

union type

The group has both the number type and the string type. How should the type of this array be written?

You can use | (vertical bar) to separate multiple types, such as

 let str: string | number = 1; str = '张三';

If the array can be strings or numbers, it can be written like this

 let arr: Array<number | string> = [1, 2, '张三'];

type alias

When a complex type or union type is excessive or used frequently, type aliases can be used to simplify the use of the type

Usage: type name = concrete type

 type CustomArray = Array<number | string>; let arr1: CustomArray = [1, 2, '张三'];

In the above code, type is used as a keyword to create a custom type

  • Type aliases can make any valid variable name
  • Recommend the name of the big hump

function type

The function type needs to refer to the type of the函数参数and返回值. There are two ways to write it here.

  • The first type: specify parameters separately, return value type
 // 单独指定函数返回值和函数参数function add(num1: number, num2: number): number { return num1 + num2; } // 指定变量形式的const add2 = (num1: number, num2: number): number => { return num1 + num2; };
  • Second, specify the parameters and return value at the same time
 // 同时指定参数和返回值type CustomFunc = (num1: number, num2: number) => number; const add3: CustomFunc = (num1, num2) => { return num1 + num2; };

Note: When a function is used as an expression, you can add a type to the function through a syntax similar to the arrow function form, which is只适用于函数表达式

void type

When our function is defined as a type with no return value, it can be represented by the keyword void

 // 没有返回值的函数type CustomFunc1 = (num1: string, num2: number) => void; const combinStr: CustomFunc1 = () => {};

If a function does not return a value, at this time, in the type of TS, the void type should be used

 const add4 = () => {}; // 如果什么都不写表示add4函数的类型为void const add5 = (): void => {}; // 这种写法明确指定返回值为void与上方的类型相同const add6 = (): undefined => { return undefined; }; // 如果指定返回值为undefined return undefined

function optional parameters

When we define a function, some parameters can be passed or not. In this case, the optional parameters of TS can be used to specify the type

For example, when using the slice method of the array, we can use slice() directly or pass in the parameter slice(1) or slice(1,3)

 const slice = (start?: number, end?: number): void => {};

? Indicates that the parameter or variable can be passed or not

Note: optional parameters can only appear at the end of the parameter list , that is, the required parameters must be before the optional parameters

object type

Objects in JS are composed of properties and methods, and the object type of TS is the description of properties and methods in the object

spelling

 // 如果有多个属性可以换行去掉间隔符号let person3: { name: string; sayHello: Function; } = { name: '王五', sayHello() {}, };

Summary: But use {} to describe object structure

Attributes take the form of属性名:类型

A function can take the form方法名(): 返回值类型or函数名: Function (without specifying a return value)

Use type aliases

Using {} directly will reduce the readability of the code and will not be recognizable. It is more recommended to use type aliases to add object types

 type PersonObj = { name: string; sayHello(): string; }; const p1: PersonObj = { name: '高大大', sayHello() { return this.name; }, };

the type of the method with parameters

If the function in the object has parameters, you can specify the parameter type in the function

 // 带参数的函数方法type PersonObj2 = { name: string; sayHello(start: number): string; }; const p2: PersonObj2 = { name: '高大大', sayHello(start) { return this.name; }, };

Method types in the form of arrow functions

 // 箭头函数形式定义类型type People = { sayHello: (start: number) => string; }; const p3: People = { sayHello() { return ''; }, };

Object optional properties

Several properties in the object are sometimes optional. At this time, we can still use ? to represent

 type Config = { method?: string; url: string; }; const func = (config: Config) => {}; func({ url: '/a' });

interface interface

When an object type is used multiple times, the interface is generally used to describe the type of the object to achieve the purpose of reuse

  • We use the interface keyword to declare an interface
  • The interface name is recommended to start with I
  • After declaring the interface, use the interface name directly as the type of the variable

No semicolon required after interface

 // 接口interface IPeople { name: string; age: number; sayHello(): void; } let p: IPeople = { name: '老高', age: 18, sayHello() {}, };

Difference between interface and custom type

The same point: you can assign types to objects

The difference: an interface can only specify a type for an object, and a type alias can specify an alias for any type

  • It is recommended to use type to define

interface inheritance

  • If there are the same properties and methods between the two interfaces, the common properties and methods can be extracted and reused through inheritance.

For example, these two interfaces have two attributes, x and y. It is possible to write twice, but it is very cumbersome.

 interface Point2D { x: number; y: number; } interface Point3D { x: number; y: number; z: number; }
  • better way
 interface Point2D { x: number; y: number } interface Point3D extends Point2D { z: number }

We use the extends keyword to realize that Point3D inherits the definition of all properties of Point2D, and has both inherited properties and its own custom properties

tuple

Tuples are used when we want to define the type of a specific index position in an array.

The original array mode can only broadly define the general types in the array, and cannot be precise to the position

A tuple is another type of array that knows exactly how many elements it contains, and what type a particular index corresponds to

 let position: [number, number] = [39.5427, 116.2317];

type inference

In TS, where the type is not explicitly stated, the type inference mechanism of TS will help provide the type

That is to say, due to the existence of type inference, type annotations can be omitted or not written in some addresses.

  • Common Scenarios Where Type Inference Occurs
  1. When a variable is declared and initialized
  2. When determining the return value of a function
 // 变量creater_name自动被推断为string let creater_name = 'gaoly'; // 函数返回值的类型被自动推断为number function addCount(num1: number, num2: number) { return num1 + num2; }

Recommendation: omit type annotations where possible ( be lazy , make full use of the ability of TS type inference to improve development efficiency)

Tip: If you don’t know the type, you can use the VSCode prompt to view the type by placing the mouse on the variable name

literal type

What are the following code types?

 // 字面量类型let str1 = '张三'; const str2 = '张三';

The answer can be obtained through the type deduction of TS

1. The variable type of variable str1 is: string

2. The variable type of variable str2 is ‘Zhang San’

Explanation: str1 is a variable (let), its value can be any string, so the type is: string

str2 is a constant (const), its value cannot be changed but can only be ‘Zhang San’, so its type is: ‘Zhang San’

At this point, ‘Zhang San’ is a literal type , that is, a special string can also be used as a type in TS

Any JS literal (object, array, number) can be used as a type

Working with Scenes and Modes

  • Usage pattern: literal types are used with union types
  • Usage scenario: used to represent an explicit set of optional values
  • For example, in the Snake game, the optional value of the direction of the game can only be any one of up, down, left, and right
 type Direction = 'left' | 'right' | 'up' | 'down'; // 使用自定义类型: function changeDirection(direction: Direction) { console.log(direction); } // 调用函数时,会有类型提示: changeDirection('up');
  • Explanation: The value of the parameter direction can only be any one of up/down/left/right
  • Advantage: Compared with string type, using literal type is more precise and rigorous

enumerate

  • The function of enumeration is similar to that of literal type + union type combination , and it can also represent a set of explicit optional values
  • Enumeration: Defines a set of named constants. It describes a value, which can be one of these named constants
 // 枚举// 创建枚举enum Direction2 { Up, Down, Left, Right, } // 使用枚举类型function changeDirection2(direction: Direction2) { console.log(direction); } // 调用函数时,需要应该传入:枚举Direction 成员的任意一个// 类似于JS 中的对象,直接通过点(.)语法访问枚举的成员changeDirection2(Direction2.Up);

Number enumeration

  • Question: What is the value of the enum member as an argument to the function?
  • Explanation: By moving the mouse into Direction.Up, you can see that the value of the enumeration member Up is 0
  • Note: Enumeration members have values, the default is: a value that starts from 0 and increments
  • We call the enumeration of the values ​​of the enumeration members as numbers:数字枚举
  • Of course, you can also initialize values ​​for members in the enumeration
 // Down -> 11、Left -> 12、Right -> 13 enum Direction { Up = 10, Down, Left, Right, } enum Direction { Up = 2, Down = 4, Left = 8, Right = 16, }

String enumeration

  • String enumeration: The value of the enumeration member is a string
  • Note: String enumerations do not have auto-increment behavior, so each member of a string enumeration must have an initial value
 enum Direction { Up = 'UP', Down = 'DOWN', Left = 'LEFT', Right = 'RIGHT', }

Enumeration Implementation Principle

  • Enums are one of the few non-JavaScript type-level extensions (not just types) features of TS
  • Because: other types are only used as types, and enumerations are not only used as types, but also provide values ​​(enumeration members are all valued)
  • That is, other types are automatically removed when compiling to JS code. However, enum types are compiled into JS code
 enum Direction { Up = 'UP', Down = 'DOWN', Left = 'LEFT', Right = 'RIGHT' } // 会被编译为以下JS 代码: var Direction; (function (Direction) { Direction['Up'] = 'UP' Direction['Down'] = 'DOWN' Direction['Left'] = 'LEFT' Direction['Right'] = 'RIGHT' })(Direction || Direction = {})
  • Description: Enumeration is similar to the above-mentioned combination of literal type + union type, and is used to represent a set of explicit optional value lists
  • In general, it is recommended to use the combination of literal type + union type , because this method is more intuitive, concise and efficient than enumeration

any type

  • Principle: any is deprecated ! This makes TypeScript “AnyScript” (loses the benefits of TS type protection)
  • Because when a value is of type any, arbitrary operations can be performed on the value and there will be no code hints
 let obj: any = { x: 0 }; obj.bar = 100; obj(); const n: number = obj;
  • Explanation: None of the above operations will have any type error prompts, even if there may be errors
  • Avoid using the any type whenever possible, unless you use any temporarily to “avoid” writing long, complex types
  • Other cases that implicitly have type any
    1. Declaring a variable does not provide a type nor a default value
    2. function parameter without type
  • Note: Since any is deprecated, the type should be provided in both cases

In project development, use the any type as little as possible


type assertion

Sometimes you will be more specific about the type of a value than TS, in which case you can use type assertions to specify a more specific type. for example,

 const aLink = document.getElementById('link');
  • Note: The type of the return value of this method is HTMLElement, which only contains attributes or methods common to all tags, and does not contain attributes such as href specific to the a tag.
  • Therefore, this type is too broad (not specific) to operate on attributes or methods specific to a tag such as href
  • Solution: In this case, you need to use a type assertion to specify a more specific type
  • Use type assertion:
 const aLink = document.getElementById('link') as HTMLAnchorElement;
  • explain:
    1. Type assertion using the as keyword
    2. The type following the keyword as is a more specific type (HTMLAnchorElement is a subtype of HTMLElement)
    3. With type assertions, the type of aLink becomes more specific, so that you can access properties or methods specific to the a tag
  • Another syntax, using <> syntax, this syntax form is not commonly known:
 // 该语法,知道即可:在react的jsx中使用会报错const aLink = <HTMLAnchorElement>document.getElementById('link');

Tip: In the browser console, get the type of the DOM element through __proto__

typeof

  • As we all know, the typeof operator is provided in JS to get the type of data in JS
 console.log(typeof 'Hello world'); // string
  • In fact, TS also provides the typeof operator: the type of a variable or property can be referenced in a type context (type query)
  • Usage scenario: According to the value of an existing variable, get the type of the value to simplify type writing
 let p = { x: 1, y: 2 }; function formatPoint(point: { x: number; y: number }) {} formatPoint(p); function formatPoint(point: typeof p) {}
  • explain:
    1. Use the typeof operator to get the type of the variable p, the result is the same as the first (type in object literal form)
    2. The environment where typeof appears in the type annotation (after the colon in the parameter name) is in the type context (different from JS code)
    3. Note: typeof can only be used to query the type of a variable or property, and cannot query other forms of type (for example, the type of function calls)

This article is reprinted from: https://www.iyouhun.com/post-230.html
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment