typescript - 如何在链表中封装 join 或 flatten 方法?
问题描述
我有一个在打字稿中构建的基本链表,带有一个有区别的联合。
type ListType<T> = {
Kind: "Cons",
Head: T,
Tail: List<T>
} | {
Kind: "Empty"
}
type ListOperations<T> = {
reduce: <U>(this: List<T>, f: (state: U, x: T) => U, accumulator: U) => U
map: <U>(this: List<T>, f: (_: T) => U) => List<U>
reverse: (this: List<T>) => List<T>
concat: (this: List<T>, l: List<T>) => List<T>
toArray: (this: List<T>) => T[]
join: (this: List<List<T>>) => List<T>
}
type List<T> = ListType<T> & ListOperations<T>
我也有一些空和缺点的构造函数:
export const Cons = <T>(head: T, tail: List<T>): List<T> => ({
Kind: "Cons",
Head: head,
Tail: tail,
...ListOperations()
})
export const Empty = <T>(): List<T> => ({
Kind: "Empty",
...ListOperations()
})
最后我实现了不同的方法:
const ListOperations = <T>(): ListOperations<T> => ({
reduce: function <U>(this: List<T>, f: (state: U, x: T) => U, accumulator: U): U {
return this.Kind == "Empty" ? accumulator : this.Tail.reduce(f, f(accumulator, this.Head))
},
map: function <U>(this: List<T>, f: (_: T) => U): List<U> {
return this.reduce((s, x) => Cons(f(x), s), Empty())
},
reverse: function (this: List<T>): List<T> {
return this.reduce((s, x) => Cons(x, s), Empty())
},
concat: function (this: List<T>, l: List<T>): List<T> {
return this.reverse().reduce((s, x) => Cons(x, s), l)
},
toArray: function (this: List<T>): T[] {
return this.reduce<T[]>((s, x) => s.concat([x]), [])
},
join: function (this: List<List<T>>): List<T> {
return this.reduce((s, x) => s.concat(x), Empty())
}
})
一切正常,但是当我尝试运行以下命令时出现编译错误:
let x = Cons(1, Cons(2, Cons(3, Cons(4, Empty()))))
let y = x.map(x => x + 4)
let z = Cons(x, Cons(y, Empty()))
z.join()
type 的 'this' 上下文
List<List<number>>
不可分配给 type 的方法的 'this'List<List<List<number>>>
。
这是因为join
方法(或者flatten
你们中的一些人可能称之为)。当我在 List 类型之外编写连接时,它可以工作,所以我的问题是:有没有办法明确告诉编译器this
需要是 type List<List<T>>
?
我已经尝试过使用extends
join: function <T1 extends List<T>>(this: List<T1>): List<T>
解决方案
那是因为您的列表是 a List<T>
,而T
它本身是 a List<T>
。正确的输入是:
join(this: List<T>): T {
然后确保它T
是一个 List 本身使用条件类型:
join(this: T extends List<*> ? List<T> : "Only nested lists can be joined!"): T
推荐阅读
- regex - 正则表达式 - 使用“替换”使用捕获组删除内容
- reactjs - 开玩笑不使用我的模拟,而是用于通过 node_modules 导入的函数
- javascript - JS中频繁调用函数初始化数组的效率
- cmake - Catkin 无法找到 gmock - Ubuntu 16.04
- javascript - 用 Google Apps 脚本替换数组中的变音符号
- .htaccess - 尝试使用 .htaccess 添加查询参数
- c# - '查询值和目标字段的数量不同。'
- swagger - 将 Swagger-UI 与 Angular-8 应用程序集成
- sql - 计数 ID 在 B 列中只有一个不同的值
- python - 什么时候在 Python 构造函数表达式中初始化对象?