TypeScript - Function (Part 2)

 

Table of contents

1. Declare this in the function

2. Other types that need to be known

2.1 void

2.2 object

2.3 unknow

2.4 never

2.5 Function

3. Other parameters (rest) and parameters

4. Parameter deconstruction

5. Assignability of functions


1. Declared in the functionthis

TypeScript will infer what should be in the function through code flow analysis, such as the following:this

const cat = {
  name: '拿破仑',
  age: 5,
  content: '',
  say: function (){
    this.content = 'hello world !!!'
  }
}

 TypeScript understands that the function cat.say has a corresponding this which is the external object user. This is enough for many cases, but there are many cases where you need more control over the object it represents. The JavaScript specification states that there cannot be a parameter named this , so TypeScript uses this syntax space to declare the type of this in the function body.

type User = {
  name: string,
  age: number
}

function getDB () {
  let filterUsers = function(params: any) :string {
    return ''
  }
  return {filterUsers};
}
interface DB {
  filterUsers(filter: (this: User) => boolean): User[];
}
 
const db = getDB();
const user = db.filterUsers(function (this: User) {
  return this.name;
});

 This pattern is common in callback-style APIs, where another object usually controls when a function is called. Note that you need to use functions instead of arrow functions to get this behavior:

const admins = db.filterUsers(()=>this.name);
// 类型“typeof globalThis”上不存在属性“name”。

2. Other types that need to be known

When dealing with function types, you need to recognize some other types that occur frequently. As with all types, you can use them anywhere, but these types are especially relevant in the context of functions. 

2.1 void

void represents the return value of a function that does not return a value. Whenever a function does not have any return statements, or returns any explicit value from those return statements, it is an inferred type:

function cat() {
  let catArr = ['波斯猫', '橘猫', '拿破仑']
  for(let i = 0; i< catArr.length; i++){
    console.log(catArr[i]);
  }
}

 In JavaScript, a function that does not return any value will implicitly return undefined. However, in TypeScript, void and undefined are not the same thing.

 Note : void is not the same as undefined.

2.2 object

A special type object is any value that is not a primitive type (string, number, bigint, boolean, symbol, null or undefined). This is different from the empty object type {}, and from the global type Object. Most likely you will never use Object.

 Note : object is not Object, object should always be used!

2.3 unknow

An unknown type represents any value. This is similar to any type, but safer because it's illegal to do anything with an unknown value:

function cat(params: any) {
  params.say();
}

function catCopy(params: unknown){
  params.say();     // “params”的类型为“未知”。
}

This is useful when describing function types, because you can describe functions that accept any value without having any value in the function body.

Instead, you can describe a function that returns a value of unknown type:

function cat(params: any): unknown {
  return params.xxx();
}

const result = cat('hello world !!!')
// 随便编译没有报错,我们还是需要注意result返回的结果。

2.4 never

Functions never return a value:

function getError(msg: string) : never {
  throw new Error(msg)
}

The never type represents values ​​that are never observed. In return types, this means that the function throws an exception or terminates the execution of the program.

Nor does it appear when TypeScript determines that there is nothing left in the union.

function fn(msg: string | number | boolean) {
  if (typeof msg === 'string'){
    // TODO
  }else if(typeof msg === 'number'){
    // TODO
  }else if(typeof msg === 'boolean'){
    // TODO
  }else{
    console.log();  // 这里类型是never
  }
}

2.5 Function

The global type Function describes properties such as binding, calling, and applying on all function values ​​in JavaScript. It also has the special property that values ​​of function types can always be called; these calls return any:

function fn(f: Function) {
  return f();
}

This is an untyped function call, which is usually best avoided because any return type is unsafe.

If you need to accept an arbitrary function, but don't intend to call it, type() => void is usually safer

3. Other parameters (rest) and parameters

In addition to using optional parameters or overloading to generate functions that can accept various fixed parameter counts, we can also use rest parameters to define functions that accept an unlimited number of parameters.

The rest parameter appears after all other parameters and uses the ... syntax:

function multiply(n: number, ...m: number[]) {
  return m.map((x) => n * x);
}
// 打印值 [10, 20, 30, 40]
const a = multiply(10, 1, 2, 3, 4);

In TypeScript, type annotations on these parameters are implicitly any[] rather than any, and any given type annotation must be of the form Array<T> or T[], or a tuple type.

Instead, we can provide a variable number of arguments from an iterable object (e.g., an array) using the spread syntax. For example, the push method of an array accepts any number of arguments:

 

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
arr1.push(...arr2);

 Note that, in general, TypeScript does not consider arrays to be immutable. This can lead to some surprising behaviour:

const args = [8, 5];
const angle = Math.atan2(...args);  // 扩张参数必须具有元组类型或传递给 rest 参数。

The best solution for this situation depends somewhat on your code, but usually a const context is the most straightforward solution:

 

const args = [8, 5] as const;
const angle = Math.atan2(...args);

Using the rest parameter may require downlevelIteration to be enabled when running against older ones.

4. Parameter deconstruction

You can use parametric destructors to conveniently unpack objects provided as parameters into one or more local variables in the function body. In JavaScript, it looks like this:

 

function sum({ a, b, c }) {
  console.log(a + b + c);
}
sum({ a: 10, b: 3, c: 9 });

Type annotations for objects follow the destructuring syntax: 

function sum({ a, b, c }: { a: number; b: number; c: number }) {
  console.log(a + b + c);
}

This might seem a bit verbose, but you can also use named types here: 

type ABC = { a: number; b: number; c: number };
function sum({ a, b, c }: ABC) {
  console.log(a + b + c);
}

Write a similar example, as shown in the following figure: 

type cat = {
  name: string,
  age: number
}
function fn(params: cat) {
  let {name, age} = params;
  console.log(name, age);
}

fn({name: '波斯猫', age: 11})

5. Assignability of functions

return type void

The void return type of a function may produce some unusual but expected behavior.

A context type with return type void does not force the function not to return something. Said another way, a contextual function type with a void return type (type voidFunc = () => void) can return any other value when implemented, but it is ignored.

Therefore, the following implementations of type() => void are valid:

type voidFunc = () => void;
 
const f1: voidFunc = () => {
  return true;
};
 
const f2: voidFunc = () => true;
 
const f3: voidFunc = function () {
  return true;
};

When the return value of one of these functions is assigned to another variable, it retains the void type:

const v1 = f1();
 
const v2 = f2();
 
const v3 = f3();

Even though Array.prototype.push returns a number and the Array.prototype.forEach method expects a function with return type void, this behavior exists to make the following code work.

const src = [1, 2, 3];
const dst = [0];
 
src.forEach((el) => dst.push(el));

There is also a special case to note that when a literal function definition has a void return type, the function must not return anything.

function f2(): void {
  // @ts-expect-error
  return true;
}
 
const f3 = function (): void {
  // @ts-expect-error
  return true;
};

Note : It can be returned in ts5.2, as shown in the figure below:

 

 

Guess you like

Origin blog.csdn.net/u014388408/article/details/131501858