TypeScript 建议:使基类表达式能够访问类类型参数

iyr7buue  于 6个月前  发布在  TypeScript
关注(0)|答案(4)|浏览(68)

搜索词

基类表达式不能引用类类型参数

建议

目前在 TypeScript 中可以通过函数动态生成基类(

function prop<T>(): T {
  // implementation detail doesn't matter
  return null as any;
}

function createDynamicClass<T>(_props: T): { new(): T} {
  // implementation detail doesn't matter
  return null as any;
}

// without generics on the main class all is fine
class C2 extends createDynamicClass({x: prop<number>()}) {
  setX(x: number) {
    this.x = x
  }
}

const c2 = new C2()
c2.x = 20
c2.setX(30)

):
并且当基类是一个具有泛型类型的“纯”类时,也可以重用泛型:

class Base<T> { x: number }
class Child<T> extends Base<T> {}

然而,目前对于生成动态类的函数来说,无法重用子类的类型:

// error: Base class expressions cannot reference class type parameters
class C3<T> extends createDynamicClass({x: prop<T>()}) {
  setX(x: T) {
    this.x = x
  }
}

const c3 = new C3<number>()
c3.x = 20
c3.setX(30)

有一个(某种程度上不太美观)的解决方法,即将生成子类的过程封装在一个函数中并使用其结果:

function generateC4<T>() {
  return class extends createDynamicClass({ x: prop<T>() }) {
    setX(x: T) {
      this.x = x
    }
  }
}

const C4 = generateC4<number>()
const c4 = new C4()
c4.x = 20
c4.setX(30)

但这相当不美观,并且在实际上不需要每个泛型时(仅用于类型检查),会为每个泛型生成一个新的类。
该提案基本上是解除这个约束,允许它被使用(就像可以轻松地用于纯类一样)。

使用案例

目前在 mobx-keystone 中使用这样的模式(一个生成动态基类的函数)来生成模型:

class Point extends Model({
    x: prop<number>(),
    y: prop<number>(),
  }) {
    @modelAction
    setXY(x: number y: number) {
      this.x = x
      this.y = y
    }
  }

const numberPoint = new Point({x: 10, y: 20})

但是为了支持泛型,用户不得不采用这种工厂模式:

class Point<T> extends Model({
    x: prop<T>(),
    y: prop<T>(),
  }) {
    @modelAction
    setXY(x: T, y: T) {
      this.x = x
      this.y = y
    }
  }

const numberPoint = new Point<number>({x: 10, y: 20})

这远非理想(而且这只是为了正确设置类型)。

示例

参见上面

检查清单

我的建议满足以下指导原则:

  • 这不会对现有的 TypeScript/JavaScript 代码造成破坏性更改

由于它只是解除了一个当前不允许的约束,所以没有当前的代码可以使用它。

  • 这不会改变现有 JavaScript 代码的运行时行为

运行时行为完全相同,只是解决了类型检查问题。

  • 这可以在不根据表达式的类型发出不同的 JS 的情况下实现
  • 这不是一个运行时特性(例如库功能、JavaScript 输出非 ECMAScript 语法等)
  • 这个特性将与 TypeScript's Design Goals 的其他部分保持一致。
nzk0hqpo

nzk0hqpo1#

我仅阅读了描述的前半部分。然而,这是否解决了你的问题?

7gcisfzg

7gcisfzg2#

你好,感谢查看!遗憾的是它没有。我只是更改了理论示例,以便它们更好地匹配使用案例。
实际案例依赖于动态类函数的类型推断才能工作。

1rhkuytd

1rhkuytd3#

如果TypeScript支持这个功能,将会非常有帮助。是否有人对此感兴趣并/或在实现它方面取得了进展?有任何未解决的问题吗?

moiiocjp

moiiocjp4#

我也面临这个问题。

相关问题