我正在编写一个库,以在javascript中实现可迭代类型的延迟计算查询。我知道已经有一些可用的选项可以实现这一点,但我的方法与公开扩展方法截然不同。
我在处理一个特殊的设计挑战时遇到了困难,我想知道是否有一些我没有想到的解决问题的方法。
我的
Enumerable<T>
类定义及其接口以及一些帮助程序如下所示:
// Iterator<T> defined in lib.es2015.iterable.d.ts
interface IteratorFunction<T> {
(this: IEnumerable<T> | void): Iterator<T>
}
interface CompareFunction<T> {
(a: T, b: T): number
}
// inspired by pattern for ArrayConstructor in lib.es5.d.ts
interface IEnumerableConstructor {
new <T>(iterator: IteratorFunction<T>): IEnumerable<T>
new <T>(iterator: IteratorFunction<T>, compare: null): IEnumerable<T>
new <T>(iterator: IteratorFunction<T>, compare: CompareFunction<T>): IOrderedEnumerable<T>
// static methods...
}
// Symbol.compare defined in separate file as a declaration merge to SymbolConstructor
interface IOrderedEnumerable<T> extends IEnumerable<T> {
readonly [Symbol.compare]: CompareFunction<T>
// overrides for thenBy()...
}
// IterableIterator<T> defined in lib.es2015.iterable.d.ts
interface IEnumerable<T> extends IterableIterator<T> {
// member methods...
}
class Enumerable<T> implements IEnumerableConstructor {
readonly [Symbol.iterator]: IteratorFunction<T>
readonly [Symbol.compare]: (null | CompareFunction<T>)
constructor (iterator: IteratorFunction<T>)
constructor (iterator: IteratorFunction<T>, compare: (null | CompareFunction<T>) = null) {
this[Symbol.iterator] = iterator
this[Symbol.compare] = compare
}
}
问题是
constructor (iterator: IteratorFunction<T>)
指假设的定义
new (iterator: IteratorFunction<T>): IEnumerable<T>
与所提供的定义相反
new <T>(iterator: IteratorFunction<T>): IEnumerable<T>
中的其他重载声明
IEnumerable<T>
,向我提供错误
类型'
可枚举<t>
'不提供与签名匹配的'
new <T>(iterator: IteratorFunction<T>): IEnumerable<T>
’。
我考虑过改变
IEnumerableConstructor
类也是泛型的,但稍后尝试执行此操作时遇到问题:
declare global {
// ...
interface ArrayConstructor extends IEnumerableConstructor/*<T>*/ { } // illegal!
interface MapConstructor extends IEnumerableConstructor { }
interface SetConstructor extends IEnumerableConstructor { }
interface StringConstructor extends IEnumerableConstructor { }
interface TypedArrayConstructor extends IEnumerableConstructor { }
interface Array<T> extends IEnumerable<T> { }
interface Map<K, V> extends IEnumerable<[K, V]> { }
interface Set<T> extends IEnumerable<T> { }
interface String extends IEnumerable<string> { }
interface TypedArray extends IEnumerable<number> { }
}
为了澄清,我宣布
TypedArray
作为那个班
Int8Array
依此类推,根据ecmascript规范进行扩展(但typescript中没有提供它的类型
lib.*.d.ts
因为它从不直接使用,这是可以理解的)。
正如我所说,这个库实现是一种完全不同的方法,它将扩展方法公开给javascript中的内置方法,我知道所有的陷阱,但是现在我正在寻找一种方法来为类提供定义。
可枚举<t>
构造函数,该构造函数尊重
IEnumerable<t>
是的。有什么想法吗?