[TS Part 2] Variables, data types, interfaces, destructuring assignment

1. Variable declaration

1.1 var

  • Scope
  • Repeat statement

1.2 let

  • block scope
  • cannot be declared repeatedly in the same block

1.3 const

  • The declaration must also be assigned a value
  • It must be stated that it cannot be changed
    • Objects can be modified
  • block scope

1.4 let vs const

Usingthe principle of least privilege, all variables except those you plan to modify should be usedconst. The basic principle is that if a variable does not need to be written to, then other people using the code cannot write to it, and think about why these variables need to be reassigned. Using const also makes it easier for us to speculate on the flow of data.

2. Basic data types

2.1 Boolean values

let isDone: boolean = false;

2.2 Numbers

let amount: number = 6;

2.3 String

  • type

  • template string

    • Support newline
    • Supports inline expressions
  • Like JavaScript, you can use double quotes or single quotes. Single quotes are recommended.

    let nickname: string = '张三';
    

You can also use template strings (newlines + embedded expressions):

let nickname: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my nickname is ${
      
       nickname }.

I'll be ${
      
       age + 1 } years old next month.`;

2.4 Array

TypeScript can operate on array elements just like JavaScript. There are two ways to define an array. The first one can be followed by [] after the element type to indicate an array composed of elements of this type:

let list: number[] = [1, 2, 3];

The second way is to use array generics,Array<元素类型>:

let list: Array<number> = [1, 2, 3];

2.5 tuples

The tuple type allows the representation of an array with a known number and type of elements, and the types of each element do not have to be the same. For example, you can define a pair of tuples whose values ​​are of type string and number respectively.

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error

2.6 Object

  • Allows assigning any value
  • But you can't call any method, even if it does
let foo: Object = {
    
    
  name: 'Jack',
  age: 18
}

Just know it, rarely used, no type checking and syntax prompts

2.7 Any

Sometimes, we want to specify a type for variables whose type is not clear at the programming stage. These values ​​may come from dynamic content, such as from user input or third-party code libraries. In this case, we don't want the type checker to check these values ​​and just let them pass the compile-time check. Then we can use the any type to mark these variables:

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

2.8 Void

voidThe type is like the opposite of the any type, which means there is no type. When a function does not return a value, you will usually see that its return value type is void:

function warnUser(): void {
    
    
  alert("This is my warning message");
}

Declaring a variable of type void is of little use because you can only assign it undefined and null :

let unusable: void = undefined;

2.9 Null and Undefined

is similar to void, but their types are not very useful:

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

By defaultnull and undefined are subtypes of all types. That is to say, you can assign null and undefined to variables of type number.

However, when you specify the --strictNullChecks tag, null and undefined can only be assigned to < a i=4> and each of them. This avoids manycommon problems. Maybe somewhere you want to pass in a or or , you can use the union type . voidstringnullundefinedstring | null | undefined

Note: We recommend using --strictNullChecks as much as possible, because it makes your code more rigorous and can greatly reduce the chance of errors.

2.10 Type inference

Sometimes you will encounter a situation where you know the details of a value better than TypeScript. Usually this happens when you clearly know that an entity has a more exact type than its existing type.

ByType assertionThis way you can tell the compiler, "Trust me, I know what I'm doing." Type assertions are like type conversions in other languages, but no special data checking or destructuring is performed. It has no runtime impact and only works during the compilation phase. TypeScript will assume that you, the programmer, have made the necessary checks.

Type assertions come in two forms. One is the "angle bracket" syntax:

let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

The other isasSyntax:

let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;

The two forms are equivalent. Which one to use is mostly a matter of personal preference; however, when you use JSX in TypeScript, only the as syntax assertion is allowed.

2.11 Others

  • ReadonlyArray<T>All mutable methods of the array are removed to ensure that the array cannot be modified after it is created.

3. Interface

One of the core principles of TypeScript is type checking the structure of a value. It is sometimes called "duck typing" or "structural subtyping". In TypeScript, the role of interfaces is to name these types and define contracts for your code or third-party code.

3.1 Basic example

function printLabel(labelledObj: {
    
     label: string }) {
    
    
  console.log(labelledObj.label);
}

let myObj = {
    
     size: 10, label: "Size 10 Object" };
printLabel(myObj);

The type checker will look at the call to printLabel. printLabel has a parameter, and requires that this object parameter have an attribute named label of type string. It should be noted that the object parameter we pass in will actually contain many properties, but the compiler will only check whether those required properties exist and whether their types match. However, sometimes TypeScript is not so loose, as we will explain a little below.

Let's rewrite the above example, this time using an interface to describe: it must contain a label attribute and type string:

interface LabelledValue {
    
    
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
    
    
  console.log(labelledObj.label);
}

let myObj = {
    
    size: 10, label: "Size 10 Object"};
printLabel(myObj);

3.2 Optional attributes

Not all properties in the interface are required. Some exist only under certain conditions, or may not exist at all. Optional attributes are commonly used when applying the "option bags" pattern, where only some of the attributes in the parameter object passed to the function are assigned values.

interface SquareConfig {
    
    
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {
    
    color: string; area: number} {
    
    
  let newSquare = {
    
    color: "white", area: 100};
  if (config.color) {
    
    
    newSquare.color = config.color;
  }
  if (config.width) {
    
    
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({
    
    color: "black"});

3.3 Read-only attributes

Some object properties can only modify their values ​​when the object is first created. You can specify read-only properties by using readonly before the property name:

interface Point {
    
    
    readonly x: number;
    readonly y: number;
}

You can construct an Point by assigning an object literal. After assignment, x and y can no longer be changed.

let p1: Point = {
    
     x: 10, y: 20 };
p1.x = 5; // error!

readonly vs const

  • Constants use const
  • Object properties use readonly

4. Destructuring assignment

4.1 Array destructuring

let input = [1, 2];
let [first, second] = input;
console.log(first); // outputs 1
console.log(second); // outputs 2

The above writing is equivalent to:

first = input[0];
second = input[1];

Use destructuring assignment to exchange variables:

[first, second] = [second, first];

Function parameter destructuring:

function f ([first, second]: [number, number]) [
  console.log(first)
  console.log(second)
]

f(1, 2)

Deconstruct the remaining parameters:

let [first, ...rest] = [1, 2, 3, 4]
console.log(first) // 1
console.log(rest) // [2, 3, 4]

Other parameters can also be ignored:

let [first] = [1, 2, 3, 4];
console.log(first); // outputs 1

Or skip destructuring:

let [, second, , fourth] = [1, 2, 3, 4]

4.2 Object destructuring

4.2.1 Basic usage

Example one:

let o = {
    
    
    a: "foo",
    b: 12,
    c: "bar"
};
let {
    
     a, b } = o;

Just like array destructuring, you can use assignment without declaration:

let a: number,
  b: number;

({
    
    a, b} = {
    
    a: 123, b: 456})

console.log(a, b) // 123 456

You can create remaining variables within the object using the ... syntax:

let {
    
     a, ...passthrough } = o;
let total = passthrough.b + passthrough.c.length;
4.2.2 Attribute destructuring and renaming

You can also give properties different names:

let {
    
     a: newName1, b: newName2 } = o;

Note that the colon here does not indicate the type. If you want to specify its type, you still need to write the complete pattern after it.

let {
    
    a, b}: {
    
    a: string, b: number} = o;
4.2.3 Default value
function keepWholeObject(wholeObject: {
    
     a: string, b?: number }) {
    
    
    let {
    
     a, b = 1001 } = wholeObject;
}

4.3 Expand operator

  • expand array
  • expand object
    • Will not expand method

4.4 Destructuring assignment for function declaration

type C = {
    
    a: string, b?: number}

function f ({
    
    a, b}: C): void {
    
    
  // ...
}

4.5 Destructuring assignment is used to load specified module members

Guess you like

Origin blog.csdn.net/qq_39335404/article/details/134210128