[英]TypeScript Overload with different return types
作為練習,我試圖將類似 Haskell 的語言中的Maybe
模式重新實現到 TypeScript 中。 到目前為止,我得到了一個令人滿意的結果,而且效果很好,我必須手動覆蓋一些類型檢查的東西。 我想更像 JavaScript,我嘗試定義一個函數映射,它可以返回純數據或數據的 Promise。
這里有一些代碼更清楚:
class Maybe<A> {
#value: A | null
private constructor(value: A) {
this.#value = value
}
static just<A>(value: A): Maybe<A> {
return new Maybe(value)
}
static nothing<A>(): Maybe<A> {
return <Maybe<A>>(<unknown>new Maybe(null))
}
static nullable<A>(value: A | null): Maybe<A> {
if (value) {
return this.just(value)
} else {
return this.nothing()
}
}
value(): A {
if (this.#value) {
return this.#value
} else {
throw new Error('Maybe has no data')
}
}
map<B>(mapper: (a: A) => Promise<B>): Promise<Maybe<B>> // I got an error here in the overloading
map<B>(mapper: (a: A) => B): Maybe<B> {
if (this.#value) {
const result = mapper(this.#value)
if (result instanceof Promise) {
return result.then((e: B) => Maybe.just(e))
} else {
return new Maybe(mapper(this.#value))
}
} else {
return Maybe.nothing()
}
}
}
我想知道是否可以定義上面定義的 map 函數?
我覺得你可以這樣做,看看評論
class Maybe<A> {
#value: A | null
// altered argument here
private constructor(value: A | null) {
this.#value = value
}
static just<A>(value: A): Maybe<A> {
return new Maybe(value)
}
static nothing<A>(): Maybe<A> {
// omitted casts
return new Maybe<A>(null);
}
static nullable<A>(value: A | null): Maybe<A> {
if (value) {
return this.just(value)
} else {
return this.nothing()
}
}
value(): A {
if (this.#value) {
return this.#value
} else {
throw new Error('Maybe has no data')
}
}
// added two separate declarations
map<B>(mapper: (a: A) => Promise<B>): Promise<Maybe<B>>;
map<B>(mapper: (a: A) => B): Maybe<B>;
// and single implementation which fits both declarations
map<B>(mapper: (a: A) => B | Promise<B>): Maybe<B> | Promise<Maybe<B>> {
if (this.#value) {
const result = mapper(this.#value)
if (result instanceof Promise) {
return result.then((e: B) => Maybe.just(e))
} else {
return new Maybe(result)
}
} else {
return Maybe.nothing()
}
}
}
所以現在Maybe.just(0).map(x=>x+1)
是Maybe<number>
但Maybe.just(0).map(x=>Promise.resolve(x+1))
是Promise<Maybe<number>>
但是對於Maybe.nothing().map(x=>Promise.resolve(x+1))
你會收到Maybe<number>
而 interface 會聲明Promies<Maybe<number>>
所以這不是一個好主意,因為你不能在不調用的情況下在運行時告訴函數返回類型
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.