我想在类中有一个方法来展平嵌套实例。我将网上的工作片段拼凑在一起,可以使用外部功能进行展平;但是从类内部引用该函数会使Typescript
变得非常慢,有bug和不稳定。结果是它计算出错误的类型。
这是相关代码
const Maybe = {
of: <A>(a: A): Maybe<A> => {
return isNully(a) ? new Just(a) : nothing
}
}
// classes
class Just<A> {
readonly _A!: A
constructor(readonly value: A) {}
fold<B>(whenNothing: B, whenJust: (a: A) => B): B {
return whenJust(this.value)
}
map<B>(fn: (a: A) => B): Maybe<B> {
return Maybe.of(fn(this.value))
}
makeTrouble<B>(fn: (a: A) => B): Maybe<B> {
return flatten(Maybe.of(fn(this.value)))
}
}
class Nothing<A> {
readonly _A!: A
static value: Maybe<never> = new Nothing()
private constructor( ) { }
fold<B>(whenNothing: B, whenJust: (a: A) => B): B {
return whenNothing
}
map<B>(fn: (a: A) => B): Maybe<B> {
return nothing
}
makeTrouble<B>(fn: (a: A) => B): Maybe<B> {
return nothing
}
}
// types
export type Maybe<A> = Nothing<A> | Just<A>
export type IsNestedMaybe<T> = T extends Maybe<Maybe<any>> ? 'T' : 'F'
export type Flatten<T extends Maybe<any>> = {
T: Flatten<T['_A']>
F: T
}[IsNestedMaybe<T>]
// values
const nothing = Nothing.value
// functions
const isNully = a => a === undefined || a === null || ( typeof a === 'number' && isNaN( a ) )
const isMaybe = <A>( obj : Maybe<A> | any ): obj is Maybe<A> => {
return ( obj instanceof Just )
}
function flatten<T extends Maybe<any>>(x: T): Flatten<T> {
return x.fold(x, a => {
if (isMaybe(a)) {
return flatten(a)
}
return x
})
}
export const head = <A>( arr : A[] ) => arr[ 0 ]
export const safeHead = <A>(as: Array<A>): Maybe<A> => {
return isNully(as) ? nothing : new Just(head(as))
}
// Example 1 -- everything works
const foo1 = Maybe.of([1, 2, 3])
.map(safeHead)
// foo1 :: Maybe<Maybe<number>>
const foo2 = flatten( foo1 )
// foo2 :: Maybe<number>
// Example 2 -- wat?
const foo3 = Maybe.of([1, 2, 3])
.makeTrouble(safeHead)
// foo3 :: Maybe<Maybe<number>>
注意:如果您在自己的编辑器中尝试此操作并遇到速度变慢的情况,建议在代码底部同时注释掉makeTrouble
方法和对foo3
的{{1}}调用。
好,这是问题
为什么在使用Maybe.of(...).makeTrouble(...)
函数时,此函数可以正确地计算类型?为什么flatten
方法不能简单地调用makeTrouble
函数呢?如何实现有效的flatten
函数?
谢谢!
打字稿的引用报告问题:https://github.com/Microsoft/TypeScript/issues/25143