Следующий машинописный код имеет правильную «внешнюю» подпись, но два оператора 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)
}
Есть ли способ заставить работать первый фрагмент кода, сохраняя строгую проверку типа?