При возврате Promise then, но получение `Property 'then' не существует для типа 'Promise<number>'`

Я пытаюсь создать функцию, которая возвращает Promise или Normal Value.

type Flow1 = <T, U>(a: T | Promise<T>, f: (a: T) => U) => U | Promise<U>

export const flow1: Flow1 = (a, f) => (a instanceof Promise ? a.then(f) : f(a))

flow1(Promise.resolve(4), (n) => n ** 2).then(console.info)

// Property 'then' does not exist on type 'number | Promise<number>'

Но я получаю сообщение об ошибке при привязке к функции. Я понятия не имею, что не так с этим набором текста.

Добавлен

export function flow1<T, U>(a: T, f: (a: T) => U): U {
  return f(a)
}
export function flow2<T, U>(a: Promise<T>, f: (a: T) => U): Promise<U> {
  return a.then(f)
}

flow1(1, (n) => n ** 2)
flow2(Promise.resolve(1), (n) => n ** 2).then(console.info)

Хорошо, есть ли способ перегрузить с тем же именем функции? :(

Попробуйте использовать перегрузки машинописного текста. Если аргумент обещание - вернуть обещание

captain-yossarian from Ukraine 24.12.2020 17:14
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
2
1
597
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Вам нужно будет изучить возвращаемое значение, чтобы увидеть, можете ли вы вызвать для него .then:

type Flow1 = <T, U>(a: T | Promise<T>, f: (a: T) => U) => U | Promise<U>

export const flow1: Flow1 = (a, f) => (a instanceof Promise ? a.then(f) : f(a))

const result = flow1(Promise.resolve(4), (n) => n ** 2);
if (result instanceof Promise) {
  result.then(console.info);
}

Вы также можете использовать перегрузку, но она требует некоторого шаблонного кода:

type Flow1 = {
    <T, U>(a: T, f: (a: T) => U): void;
    <T, U>(a: Promise<T>, f: (a: T) => U): Promise<U>;
};
const flow1: Flow1 = <T, U>(a: T | Promise<T>, f: (a: T) => U) => (a instanceof Promise ? a.then(f) : f(a));
flow1(Promise.resolve(4), (n: number) => n ** 2).then(console.info)

Не могли бы вы рассказать мне, как написать перегрузку с выражением function? Есть ли способ добиться этого? Нравится ts function flow1(): T function flow1(): Promise<T> { // ... }

KHW1031 24.12.2020 17:41

В смысле без отдельного type? Это было бы очень некрасиво, но в основном просто скопируйте и вставьте содержимое типа поверх Flow1. const flow1: { <T, U>(a: T, f: (a: T) => U): void; и т. д. Слишком тяжело читать.

CertainPerformance 24.12.2020 17:43

Другие вопросы по теме