实现流畅的通用 class 方法打字稿

Implementing fluent generic class methods Typescript

如何在集合上实现流畅的(可链接的)通用映射函数 class?考虑以下:

class Array_<T> {
    private _arr: T[]

    constructor(iterable: Iterable<T>) { this._arr = [...iterable] }

    [Symbol.iterator]() { return this._arr[Symbol.iterator]() }

    map<Y>(projector: (item: T) => Y): Array_<Y> {
        return new Array_((function* (iterable: Iterable<T>) {
            for (const element of iterable) {
                yield projector(element)
            }
        })(this))
    }
}

class ArrayCustom<T> extends Array<T> { }

let mappedArr = new ArrayCustom([1,2,3]).map(element=>element.toString())

mappedArr的推断类型是Array_<string>,但我希望它是ArrayCustom<string>

你可以做的是在ArrayCustom中重新定义map:

class ArrayCustom<T> extends AppArray<T> {
  map<Y>(projector: (item: T) => Y): ArrayCustom<Y> {
    return super.map(projector)
  }
}

// let mappedArr: ArrayCustom<string>
let mappedArr = new ArrayCustom([1, 2, 3]).map(element => element.toString());

PS:我将您的 Array 更改为 AppArray - 我遇到了 Array 的重复类型编译错误,因为它已经作为全局类型存在。

您不能使用 Polymorphic this types, as you return a new object in map for the fluent interface every time. That would require the object to be the same. Also it is not possible to parametrize the returned array type, as TypeScript does not support higher kinded generic types(请参阅 jcalz 的评论)。

旁注: 如果你想做数组的浅克隆,映射所有项目并且不依赖异步生成器,你可以使用 Array.from:

更容易地实现 map
map2<Y>(projector: (item: T) => Y): AppArray<Y> {
  return new AppArray(Array.from(this, projector));
}

Playground