获取另一个函数的参数类型以在另一个函数的...rest参数中使用

问题描述 投票:0回答:1

对于一些背景,我正在尝试编写一个函数,该函数可以在 Expo 项目中调用 React Native Firebase Analytics 的任何现有方法,该方法负责计算应用程序是否在 Expo Go 中运行。如果是,我不会调用

analytics()
方法,因为它不可用。

Firebase Analytics 方法类型作为类提供:https://github.com/invertase/react-native-firebase/blob/566470cfc0e919a46c0a119835187257bf046df7/packages/analytics/lib/index.d.ts#L801

我想做的是使用泛型类型,让我传入要调用的方法的名称,然后获取该方法的参数类型并将它们应用于

...rest
参数。泛型类型似乎适用于方法名称,但我无法正确获取
...rest
的类型。这就是我所拥有的:

import { FirebaseAnalyticsTypes } from '@react-native-firebase/analytics';

import { isExpoGo } from '~/environment';

let analytics; // Also unclear how to type this
if (!isExpoGo) {
    analytics = require('@react-native-firebase/analytics').default;
}

/**
 * Call a Firebase Analytics function.
 */
export const analyticsFn = async function <
    F extends keyof FirebaseAnalyticsTypes.Module
>(fnName: F, ...rest: Parameters<FirebaseAnalyticsTypes.Module[F]>) {
    console.log('Analytics:', fnName, ...rest);
    if (isExpoGo) return;
    return await analytics()[fnName](...rest);
};

Parameters<>
内的部分抛出此错误:

Type 'Module[F]' does not satisfy the constraint '(...args: any) => any'.
  Type '((name: string, params?: { [key: string]: any; } | undefined, options?: AnalyticsCallOptions | undefined) => Promise<void>) | ((enabled: boolean) => Promise<...>) | ... 44 more ... | FirebaseApp' is not assignable to type '(...args: any) => any'.

我也尝试过

Parameters<typeof FirebaseAnalyticsTypes.Module[F]>
但它会自动格式化为
Parameters<(typeof FirebaseAnalyticsTypes.Module)[F]>
,这显然不起作用。

typescript react-native typescript-generics react-native-firebase
1个回答
-1
投票

您遇到的错误与 Parameters 类型 的约束有关。参数实用程序类型需要函数类型作为其参数,但在这种情况下,您尝试使用键 F 从对象类型

FirebaseAnalyticsTypes.Module
访问方法。要解决此问题,我建议您提取实际的函数类型从模块并将其应用到参数实用程序类型。它看起来像这样:

import { FirebaseAnalyticsTypes } from '@react-native-firebase/analytics';

import { isExpoGo } from '~/environment';

/**
 * Call a Firebase Analytics function.
 */
export const analyticsFn = async function <
    F extends keyof FirebaseAnalyticsTypes.Module
>(fnName: F, ...rest: Parameters<FirebaseAnalyticsTypes.Module[F]>
) {
    console.log('Analytics:', fnName, ...rest);
    if (isExpoGo) return;
    return await analytics()[fnName](...rest);
};

现在应该可以正常工作了。

Parameters<FirebaseAnalyticsTypes.Module[F]>
会从
FirebaseAnalyticsTypes.Module
对象中正确推断出 fnName 对应函数的参数类型。

:) 希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.