Typescript dual syn c / asyn c возвращаемый тип - PullRequest
1 голос
/ 05 августа 2020

Следующий машинописный код имеет правильную «внешнюю» подпись, но два оператора return возвращают ошибку ( игровая площадка ).

export function using<F, R = void | Promise<void>>(
  value: F,
  init: (value: F) => R
): R extends Promise<void> ? Promise<F> : F {
  const r = init(value)
  if (r === undefined) return value
  return r.then(() => value)
}

Простое исправление, предложенное known-bmf - использовать перегрузку функции как таковую:

export function using<F>(value: F, init: (value: F) => Promise<void>): Promise<F>
export function using<F>(value: F, init: (value: F) => void): F
export function using<F>(value: F, init: (value: F) => void | Promise<void>): F | Promise<F> {
  const r = init(value)
  if (r === undefined) return value
  return r.then(() => value)
}

Но тогда вы теряете проверку строгой типизации в реализации функции, например, следующее неверно но не возвращает ошибок компиляции:

export function using<F>(value: F, init: (value: F) => Promise<void>): Promise<F>
export function using<F>(value: F, init: (value: F) => void): F
export function using<F>(value: F, init: (value: F) => void | Promise<void>): F | Promise<F> {
  const r = init(value)
  if (r === undefined) return Promise.resolve(value)
  return r.then(() => value)
}

Есть ли способ заставить работать первый фрагмент кода, сохраняя строгую проверку типа?

1 Ответ

1 голос
/ 05 августа 2020

Вы можете использовать перегрузку функции , чтобы предоставить несколько подписей для одной и той же функции.

Пример кода здесь

В зависимости от того, как вы вызываете using, он вернет F или Promise<F>.

Пример использования здесь

...