It’s 2022, Typescript: Basics 1.
During this period of time, TS has been developing at its peak. I wanted to take a break and read other people’s posts to learn from them, but after searching for nearly ten posts, I found that they were either superficial or there were some deviations. I did not find any satisfactory ones. So I decided to look at the official documents. After learning for a period of time, I am ready to write a series of TS knowledge, from basic types, objects, functions, modules and so on, to the application in VUE and React, for the reference of students who need it. Among them, I used a lot of examples of official documents, feel that my learning experience is not good or incorrect friends, welcome criticism and correction.
TS is a superset of JS. Before learning TS, it is better to have some JS foundation. This article covers only typescript installation and the various base types. Students who need to know more can read other chapters or consult official documents.
[toc]
(1) Installation and compilation
To use TS, you need to be able to install it. Typescript requires a Node environment. Make sure you have Node installed. If you haven’t already installed Node, you can download it from [node.js].
Open the project directory for initialization:
npm init -y
Copy the code
NPM, YARN, and PNPM are recommended. You can choose one of the three tools (NPM is a package management tool provided by Node, and you can use it freely. Yarn or PNPM must be installed in advance.
# with npm
npm install typescript --save-dev
# with yarn
yarn add typescript --dev
# with pnpm
pnpm add typescript -D
Copy the code
When you install TS, the compilation tool TSC is also installed automatically. After the installation is complete, create an app.ts in the root directory of the project.
// app.ts
const str = 'app'
console.log(str.charAt(0))
Copy the code
TSC can be run in any of the following ways, and the successful compilation will create an app.js file in the same directory as app.ts.
The app.ts file in the current directory is compiled to app.js
# npm
npx tsc app.ts
# yarn
yarn tsc app.ts
# pnpm
pnpm tsc app.ts
Copy the code
App. Js:
const str = 'app'
console.log(str.charAt(0))
Copy the code
This js file looks the same as app.ts because we don’t have type constraints in app.ts. More on types later. Now let’s give app.ts a little “error”. Replace STR with an array. The editor will mark the error code with a red wavy line, and if you run YARN TSC app.ts from the command line, the console will report an error.
// app.ts
const str = ['a'.'p'.'p']
console.log(str.charAt(0)) / / charAt would be
Copy the code
However, the error code will still be compiled into a JS file. We can add the relevant configuration instructions compiled after the TSC command to control. For example, with **–noEmitOnError**, no JS file will be generated if an error is reported.
tsc --noEmitOnError hello.ts
Copy the code
But ts compilation configuration items are very many, if every time through the command line to add instructions to carry out the relevant control, no doubt very tedious. So we can write the configuration in tsconfig.json, so that when we execute TSC, the compiler will, by default, step from the current directory to the upper directory and read the configuration items in tsconfig.json.
(2) Configuration file: tsconfig.json
When you run the TSC command, you can add instructions to specify the configuration. However, we prefer to configure the related instructions in tsconfig.json to reduce repetitive and tedious operations. In Vue, React and other framework projects, the tsconfig.json file has been initially configured. This article will only share the basics of the solution, and the configuration chapter will be published in the future.
(iii) Type basis
Some of the TS base types are introduced here, and the progression of the types will be covered separately in a subsequent chapter. Be careful not to confuse base types with JS base data types. Base types can be understood as the types built into TS, rather than the ones we’ve defined artificially. TS has a variety of base types that can be combined to get the human-defined types we need. TS uses a colon (:) and the type name to comment the variable when declaring it. If no type annotation is added, TS automatically deduces what type the variable belongs to by type inference based on the variable’s initial value. If there is no initial value, it is inferred to be of type any.
1. Original basic data types
-
String: a string type. Note that string already has a special meaning in JS, and that lowercase string is the type name Typescript uses to represent strings. In other words, we use lowercase string instead of uppercase string for annotation variables. Same with number and Boolean.
-
Number: indicates the number type.
-
Boolean: Boolean type;
// Specify the type of the variable. The value of num must be number let num: number; let str: string = 'typescript'; // Type inference: TS automatically infer that bool is of type Boolean let bool = true; Copy the code
2. Array
Array is an Array type, one of the object types. There are several groups of members in an Array, so when you declare an Array variable, you also need to add Type comments to the Array members. There are two common methods: Type[] and Array
. The latter involves the concept of generics, which will be covered later. Where, Type refers to the Type of an array member, which can be a primitive Type or an artificially defined Type (deformation of arrays, tuple types, is covered in the section on object types). For example, to declare an array variable that holds a string:
let arr1: string[];
// Can also be like the following
let arr2: Array<string>
Copy the code
3. object
Object types are more common types. This article only gives some simple definitions, which will be introduced separately in subsequent chapters. A variable of an object type can store multiple data through key-value pairs. To define an object type, you can simply list its properties and their types:
// Define a variable obj with name, age, gender attributes
let obj: {name: string.age: number.gender: 'gg' | 'mm'};
Copy the code
Then obj must have name, age and gender, and the attribute value should be of the corresponding type.
// The type is not correct
obj = {name: 'yy'.age: 22.gender: 'mm'.beauty:100};
// Error: gender attribute missing
obj = {name: 'yy'.age: 22};
// Assign correctly
obj = {name: 'yy'.age: 22.gender: 'mm'};
Copy the code
If you want to make an attribute optional, use the question mark “?” after the attribute name when defining the object type. :
// Define gender as optional
let obj: {name: string.age: number, gender? :'gg' | 'mm'};
/ / right
obj = {name: 'yy'.age: 22.gender: 'mm'};
// Also true, because gender is optional
obj = {name: 'yy'.age: 22};
Copy the code
After a property is defined as optional, once the assignment to the object, not into the property, its value will be undefined (note that this is the first define gender: ‘gg’ | ‘mm | undefined different.)
For example, if there are optional parameters in the function, the gender attribute may be undefined, so we need to add an exclamation mark (“!”) after the attribute. Make a non-null assertion to make it clear that it is not undefined.
function fn(obj: { name: string, age: number, gender? :'gg' | 'mm' }){
/ / use! Make a non-null assertionobj.gender! .replace(' '.' ')}Copy the code
4. Union Types
Union Types refers to the use of “|” symbols to multiple Types of united into a type, a joint variables of type, its value can be joint type of any child type.
// define a as the union type, then a can be either string or number
let a: string | number;
// A can be a string
a = 'union types';
// A can also be number
a = 100;
Copy the code
In the function of the parameters used in the joint type, there are some matters needing attention, such as in the example above, a is of type string | number, at this time a can’t call the string method, because a, may be a number. Similarly, numeric methods cannot be called directly. Of course, you can’t assign directly to a string variable or a number variable.
let a: string | number;
// A can be a string
a = 'union types';
let b: string;
let c: number;
// When strict null checking is enabled, the following two assignments are invalid
b = a;
c = a;
Copy the code
Of course, if each subtype has a common method, then that common method can be called. For example: arrays and strings have slice method, the joint type string | number [] variable can call slice method.
function func(obj: string | number[]){
The slice method can be called directly
const a = obj.slice()
}
Copy the code
5. Type Alias Indicates the Type Alias
Use the type keyword to give your type an alias that can be used to refer to the type later.
type Point = {
x: number;
y: number;
};
type ID = number | string;
// Use the type alias Point
let p: Point = {
x: 123.y: 222
}
Copy the code
6. Interfaces
The interface keyword defines an interface, which is actually an object type, to specify the shape of an object.
interface Point {
x: number;
y: number;
}
function printCoord(pt: Point) {
console.log("The coordinate's x value is " + pt.x);
console.log("The coordinate's y value is " + pt.y);
}
printCoord({ x: 100.y: 100 });
Copy the code
A brief description of the difference between an interface and a type alias:
- Interface can passextendsKeyword toinheritanceAnother interface, and type uses ampersand to connect different object properties;
interface Animal {
name: string,}// Inherit the Animal interface
interface Dog extends Animal {
skull: number,}// Inherits the Animal interface property name
const dog:Dog = {
skull: 10.name: 'wangcai'
}
// Type aliases extend attributes with ampersand
type Dog2 = Animal & {
skull: number
}
Copy the code
- Interface can be extended, but Type cannot
interface Animal {
name: string,}interface Dog extends Animal {
skull: number,}// Expand the interface
interface Dog {
age:number
}
Skull skull skull age
const dog:Dog = {
name: 'wangcai'.skull:12.age: 2
}
// Declare a Dog2 type
type Dog2 = {
skull:number
}
// An error will be reported, Dog2 repeated
type Dog2 = {
name: string
}
Copy the code
- Interface defines the shape of an object, and type can be used not only for objects but also for other types
type TypeA = {
name: string
}
type TypeB = string | number
type TypeC = TypeA | TypeB
Copy the code
7. Cross types
The ampersand symbol is used to join multiple types. Variables belonging to the cross type A & B satisfy both constraints of A and B.
type TypeA = string | number;
type TypeB = Array<boolean> | number;
// TypeC satisfies both TypeA and TypeB, so TypeC is number
type TypeC = TypeA & TypeB;
// A is the number type
let a: TypeC = 3;
// b is TypeA, and its value is a string, so it cannot be assigned to a
let b: TypeA = '123'
a = b; / / an error
Copy the code
Can also be used to extend properties of object types:
type A = {
name: string
}
type B = {
age: number.gender: "Male" | "Female"
}
// Type C satisfies both A and B, i.e., C contains all attributes of A and all attributes of B,
// To implement attribute extension
type C = A & B
let c: C = {
name: "cc".age: 18.gender: "Male"
}
Copy the code
Pay attention to the differences & and | : “&” can merge multiple object types of properties, to get the new object types include all types of all the other attributes;” &” Common subtypes can be obtained between multiple types;” | “can be combined multiple types, the value of the new types of type can only meet one seed.
Literal Types
A literal can be a value of any type. Multiple literals of different types can be combined, and the resulting method cannot be legally called because the variable may be of another type that does not contain the method (as with the union type). Therefore, type reduction or type assertion is required. Note that literal types are bound only by type annotations in variable declarations. If there is no type annotation, the type is determined by the result of type inference.
// Define gender as either male or female
let gender: 'male' | 'woman' = 'male'
// Gender2 Inferences the string type from the type
let gender2 = 'male'
// Multiple types of literals are combined
let x: 'Unknown' | 1 | {y: 1}
// Cannot be called legally in strict type checking
x.split('know')
// It is valid after type assertion
<string>x.split('know')
Copy the code
9. Null and undefined and non-null assertions
Two null – value types, and the same difference in JS. Turning strict null checking on/off affects the behavior of null types. We use the exclamation mark “!” after a variable when we know it will not be empty. , make a non-null Assertion. This is particularly important in functions.
type MyType = string | number | undefined;
let value: MyType = 'I love China';
// Make a non-null assertion on valuevalue! .split(' ');
Copy the code
10. Enums Enum type
An enumerated type is a collection of constants that are meaningfully named. Unlike other types, which are simply types, enumerated types are values that can be used. Declaring a variable as a value of enumerated type with the enum keyword allows us to ignore the actual value of the variable and use a more meaningful name to represent the actual value. For example, in expressing gender, we can simply use the numbers 1 and 2 for male and female. So in practice, we need to know whether 1 is male or 1 is female. When data is transferred from the front end to the back end, the back end partner needs to know which number represents which gender. That’s not very friendly for us. So, we can use an enumerated type to define a set of constants that represent gender and then use the constants by name.
enum Gender {
male: 1.female: 2.secret: 3
}
Copy the code
Enumeration types include numeric enumeration, string enumeration, heterogeneous enumeration, and so on. This is a brief look at the existence of enumerations, and an in-depth article on them will be written later.
11. any
Any can refer to any type and can be assigned to variables of any type.
// Give the variable anyscript an any type with the value of the number 123
let anyscript: any = 123;
// Give the typescript variable a string type
let typescript: string = 'typescript';
// After the assignment, typescript becomes 123 and its type changes
typescript = anyscript;
// The compiler considers typescript variables to be string and allows us to call string methods
typescript.split('c')
// The fact that the typescript variable has already changed to the number 123 will cause the string method to be called
Copy the code
This seemingly convenient any type causes problems at this point, causing type pollution. Therefore, we should avoid using any to avoid the pitfalls of Anyscript.
12. Unknown versus type assertion
Unknown is used to indicate an unknown type. Similar to any, its value can be of any type. The difference is that if a variable is of type unknown, it cannot call any methods or be assigned to other variables until it is explicitly of an exact type. You can use type assertions to artificially determine the exact type of an unknown variable. After all, you always know more about Typescript! Type assertions can be made in one of two ways: use a as Type or use Angle brackets:
a before a variable that requires Type assertion to make it clear that variable A is Type Type. Note that the type assertion is temporary, so it does not change the type of the original unknown variable.
// Declare an unknown variable a, a string variable b
let a: unknown = 'I am unknown type';
let b: string;
// Error: a is of unknown type, and its type is not specified.
// cannot be assigned to the string variable b, even if a itself is actually a string
b = a;
// Use a type assertion to specify that the specific type of a is string,
// Can then be assigned to string B
Type assertion with as can be wrapped in parentheses to operate on the variable a that follows the assertion
b = a as string;
b = (a as string) + '! ';
// Type assertions can also be made using the form
a
b = <string>a;
// The type of a is still unknown
Copy the code
You may find using unknown types tedious. However, unknown is safer to use than any. Therefore, if you need to use an ambiguous type, you should prefer unknown to any. After all, no one wants to change a cup of tea, a circle, a BUG all day (and even find out the cause of the error).
13. Never and void
Void is used to indicate that the function returns a null value; Never is used to indicate that a value should not exist or that a function should not return a value.
14. Uncommon types
Bigint and Symbol are basic data types that have been added since ES6 and are not often used in everyday work. These two types in TS are the same as in JS.
-
bigint
// Use BigInt to create a variable of type BigInt const oneHundred: bigint = BigInt(100); // Use the literal syntax number + n to create variables of type bigint const anotherHundred: bigint = 100n; Copy the code
-
Symbol
Symbol is a basic data type added after ES6. Each Symbol variable has a unique value. Even if the same parameter is passed in, the result will never be equal. This is usually done using the Symbol function.
Use the Symbol function to create a variable/constant of type Symbol const first1 = Symbol("1"); const first2 = Symbol("1"); first1 === first2 // Always false Copy the code
So much for the basics of typing, the next article will focus on the issues you need to be aware of when using various types in functions, such as typing accuracy. If there is something wrong with the description of this article, please point it out. See you next time!