Функция-оболочка Typesafe в Typescript

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

Функция упаковки cachify выглядит так:

// cache.ts
const cachify = async <T>(fn, args): Promise<T> => {
  const key = constructHashKey(args)
  const cachedEntry = get(key)

  if (cachedEntry) {
    return cachedEntry
  } else {
    const entry = await fn(...args)
    put(key, entry)
    return entry
  }
}

Вот пример использования функции переноса:

// userService.ts
const getUserProfilePhotoUrl = async (id: string, size: string): Promise<string> => {
  return cachify<string>(fetchPhotoUrl, [
    id,
    size
  ])
}

Функция fetchPhotoUrl имеет сигнатуру (id: string, size: string): Promise<string>.

Однако, если я добавлю какой-нибудь произвольный аргумент в массив [id, size], я не получу никаких ошибок типа. Как мне сообщить об этом Typescript?

Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой 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
0
1 635
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

const cachify = async <T, A extends [any] | any[]>(fn: (...a: A) => Promise<T>, args: A): Promise<T> => {
    const key = constructHashKey(args)
    const cachedEntry = get(key)

    if (cachedEntry) {
        return cachedEntry
    } else {
        const entry = await fn(...args)
        put(key, entry)
        return entry
    }

}

declare function fetchPhotoUrl(id: string, size: string): Promise<string>;
const getUserProfilePhotoUrl = async (id: string, size: string): Promise<string> => {
    return cachify(fetchPhotoUrl, [
        id,
        size
    ])
}

Если все, что вы будете делать, это просто пересылать параметр в этой версии, это может упростить задачу:

const cachify = <T, A extends [any] | any[]>(fn: (...a: A) => Promise<T>): ((...args: A) => Promise<T>) => {
    return async function (...args: A) {
        const key = constructHashKey(args)
        const cachedEntry = get(key)

        if (cachedEntry) {
            return cachedEntry
        } else {
            const entry = await fn(...args)
            put(key, entry)
            return entry
        }
    }
}

declare function fetchPhotoUrl(id: string, size: string): Promise<string>;
const getUserProfilePhotoUrl = cachify(fetchPhotoUrl)

getUserProfilePhotoUrl("id", "");

getUserProfilePhotoUrl полностью безопасен для типов, вы получаете всплывающую подсказку для имен параметров, если наводите курсор на функцию, но не при фактическом завершении кода (это должно быть исправлено в будущем).

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