【问题标题】:Why should we use the “extends” keyword but not the type itself?为什么我们应该使用“extends”关键字而不是类型本身?
【发布时间】:2020-07-27 07:44:26
【问题描述】:

我读过这篇文章https://www.typescriptlang.org/docs/handbook/generics.html#generic-constraints

我想知道为什么我们必须在这里使用extends 关键字?

interface Lengthwise {
  length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
  console.log(arg.length); // Now we know it has a .length property, so no more error
  return arg;
}

为什么不这样做呢?我使用extends关键字有什么区别?

interface Lengthwise {
  length: number;
}

function loggingIdentity(arg: Lengthwise): Lengthwise {
  console.log(arg.length); // Now we know it has a .length property, so no more error
  return arg;
}

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    这不像你总是必须这样做。大多数时候,它恰好是你想要的。

    当你这样做时:

    function loggingIdentity<T extends Lengthwise>(arg: T): T {
    

    然后loggingIdentity 将返回与其接受的T 完全相同的子类型。这是比说更有力的承诺:

    function loggingIdentity(arg: Lengthwise): Lengthwise {
    

    它只承诺返回一个Lengthwise,它不必匹配接受的参数。

    让我来说明这一点。

    interface Lengthwise {
      length: number;
    }
    
    declare function generic<T extends Lengthwise>(arg: T): T;
    declare function concrete(arg: Lengthwise): Lengthwise;
    
    const myArgument = { length: 1, foo: 'bar '};
    
    const first = generic(myArgument).foo; // string
    const second = concrete(myArgument).foo; // Compile-time error — the knowledge of `foo` was lost
    

    如您所见,second 上没有名为 foo 的属性。 concrete 只承诺返回 Lengthwise,而不是提供给它的 Lengthwise 的确切子类型。

    【讨论】:

      【解决方案2】:
      • 不同之处在于使用extends这意味着泛型或任何扩展都可以从接口继承所有属性并添加更多属性,但在第二种情况下,您不能在接口中添加超过length属性.所以你不能添加多个属性,这里是length 属性,但是通过使用extends,你可以在接口的属性旁边使用任意数量的参数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-25
        • 2021-10-25
        相关资源
        最近更新 更多