awesome-typescript icon indicating copy to clipboard operation
awesome-typescript copied to clipboard

练习第一题

Open C-G-L-A-D opened this issue 2 years ago • 1 comments
trafficstars

type User = {
  id: number;
  kind: string;
};

function makeCustomer<T extends User>(u: T): T {
  // 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'.
  return {
    id: u.id,
    kind: 'customer'
  }
}

T 继承 User,所以 T 类型是 User 的子类。子类包含父类的属性和方法,但子类的属性和方法,父类不一定拥有。 makeCustomer 函数要求返回 T 类型的数据,那么返回值不仅需要是包含 id 属性 和 kind 属性的 对象,还必须包含 T 类型特有的属性和方法。 因此有两种修改方案:

  1. 返回 T 类型的数据
function makeCustomer<T extends User>(u: T): T {
  return {
    // 使用扩展运算符,获取 u 中的所有属性和方法
    ...u,
    // 重新赋值的属性放在后面,覆盖 u 中的 id 和 kind 属性。
    id: u.id,
    kind: 'customer'
  }
}
  1. 将返回值类型修改为 User 类型
function makeCustomer<T extends User>(u: T): User {
  return {
    id: u.id,
    kind: 'customer'
  }
}

C-G-L-A-D avatar Dec 08 '22 08:12 C-G-L-A-D

return { id: u.id, kind: 'customer', } as T 也可以,不知道这样改合适不

SweeperDuan avatar Sep 05 '23 08:09 SweeperDuan