Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

Preface:

If you want to start from scratch, please start from the first post juejin.cn/post/701033…

The first question

Investigation contents:

Understanding extends.

Why does the following code prompt an error and how to solve it?

type User = { id: number; kind: string; }; function makeCustomer<T extends User>(u: T): T { return { id: u.id, kind: 'customer'}} // Error (TS compiler version: v4.4.2) // Type '{id: number; kind: string; }' is not assignable to type 'T'. // '{ id: number; kind: string; }' is assignable to the constraint of type 'T', // but 'T' could be instantiated with a different subtype of constraint 'User'.Copy the code

Answer key

The extends extends meaning is a type constraint. T is constrained by User and must contain the types specified in User, but is not limited to the types specified in User. That is to say, T may have a broader type, so an error is reported when an extra type is returned without processing. The solution is to deal with the redundant types

type User = { id: number; kind: string; }; // T assignable User function makeCustomer<T extends User>(u: T): T { return { ... u, id: u.id, kind: 'customer' } }Copy the code

We simply return the extra attributes by extending the operator.

The second question

In this problem, we want the parameters a and B to be of the same type, i.e. both a and B are of type number or string. When their types are inconsistent, the TS type checker automatically prompts the corresponding error message.

function f(a: string | number, b: string | number) {
  if (typeof a === 'string') {
    return a + ':' + b; // no error but b can be number!
  } else {
    return a + b; // error as b can be number | string
  }
}
​
f(2, 3); // Ok
f(1, 'a'); // Error
f('a', 2); // Error
f('a', 'b') // Ok
​
Copy the code

Answer key

Function overloading

function f(a: string, b: string): string
function f(a: number, b: number): number
function f(a: string | number, b: string | number ): string | number {
  if (typeof a === 'string') {
    return a + ':' + b;
  } else {
    return ((a as number) + (b as number));
  }
}
​
f(2, 3); // Ok
f(1, 'a'); // Error
f('a', 2); // Error
f('a', 'b') // Ok
Copy the code

Function overloading is the clearest and easiest because of the limited number of situations that can occur.