【问题标题】:Let classes inherit from type aliases让类从类型别名继承
【发布时间】:2017-08-06 14:22:54
【问题描述】:

我尝试创建一个用户类并希望能够从类型别名继承:

type PlainUser = { email: string }

class User extends PlainUser {
  constructor (initialValues: PlainUser) {
    this.email = initialValues.email
  }

  update () { ... }
}

这当然行不通,但我希望拥有以下语义,而不必重复 email(以及我没有显示的所有其他字段以保持简短):

type PlainUser = { email: string }

class User {
  email: string

  constructor (initialValues: PlainUser) {
    this.email = initialValues.email
  }

  update () { ... }
}

这可以通过流量实现吗?

【问题讨论】:

    标签: javascript class inheritance flowtype


    【解决方案1】:

    据我所知,您至少可以使用implements 强制User 类实现PlainUser 接口(是的,您必须将其更改为接口)。

    interface PlainUser {
      email: string;
    }
    
    class Foo implements PlainUser {
    }
    

    (tryflow)

    上面的代码在 Flow v0.41 中产生以下错误,因为 Foo 没有指定 email 属性:

    7: class Foo implements PlainUser {
                            ^ property `email` of PlainUser. Property not found in
    7: class Foo implements PlainUser {
             ^ Foo
    

    当然,这并不完全符合您的要求。但至少你可以自动检查User 实现了PlainUser,而不是什么都没有。

    【讨论】:

      【解决方案2】:

      你只能从类扩展,你的类型别名是一个接口,所以你必须在这里使用implement。自 this suggestion was implemented 以来,TypeScript Salsa 允许执行以下操作:

      type PlainUser = { email: string };
      
      class User implements PlainUser {
        constructor (initialValues: PlainUser) {
            this.email = initialValues.email;
        }
      }
      

      如果不使用salsa,则必须显式声明继承的属性:

      type PlainUser = { email: string };
      
      class User implements PlainUser {
          public email: string;
          constructor (initialValues: PlainUser) {
              this.email = initialValues.email;
          }
      }
      

      Playground

      【讨论】:

      • 这个问题是关于Flowtype的,所以这似乎没有回答这个问题。
      【解决方案3】:

      我承认这最初是一个令人头疼的问题,但是像您想要做的事情是非常可能的。它确实需要重新考虑这种方法。

      首先,您需要以 class 而不是对象字面量开头。直觉上这是有道理的,因为这也是 javascript 的工作方式。

      class User {
        email: string;
      }
      

      接下来您要使用流的$Shape 转换。这会将您的类型转换为类的可枚举属性。

      type PlainUser = $Shape<User>;
      
      const Bob: PlainUser = { email: "bob@bob.com" }
      

      const BobProperties: PlainUser = { ...new PlainUserClass("bob@bob.com") }
      

      最后,像往常一样扩展 User 类。

      class AdminUser extends User {
        admin: true;
      }
      

      example

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-11
        • 1970-01-01
        • 2015-05-18
        • 2011-01-10
        • 1970-01-01
        相关资源
        最近更新 更多