簡體   English   中英

具有不同返回類型的 TypeScript 重載

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM