学好TS,就靠这个系列(一)

889 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

序言:

这是搞定 TS 第一篇,如果没有基础的小伙伴想要从零搞定 TS ,请从第一篇开始juejin.cn/post/701033…

第一题

考察内容:

对 extends 的理解。 ​

以下代码为什么会提示错误,如何解决呢。

type User = {
  id: number;
  kind: string;
};
​
function makeCustomer<T extends User>(u: T): T {
  return {
    id: u.id,
    kind: 'customer'
  }
}
 // Error(TS 编译器版本: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'.

题解

extends 的含义是类型约束, T 受到 User的约束,必须包含User 中规定的类型,但是不局限于 User 中的类型,也就是说 T 的类型也许会更广泛,所以返回时,多余类型没有处理已导致报错。解决方案就是处理好多余的类型

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

我们通过扩展运算符将多余的属性承载返回即可。 ​

第二题

考察内容 : 函数重载 本道题我们希望参数 a 和 b 的类型都是一致的,即 a 和 b 同时为 number 或 string 类型。当它们的类型不一致的值,TS 类型检查器能自动提示对应的错误信息。

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

题解

函数重载

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

因为可出现的情况有限,所以使用函数重载最为清晰简单。