是否可以使用带有通用参数的const值?
对于此代码
import * as R from 'ramda';
enum ApiActionType {
requested,
completed,
failed,
cancelled,
}
type ApiActionTypeKeys = keyof typeof ApiActionType;
enum ChangedActionType {
changed,
}
type ChangedActionTypeKeys = keyof typeof ChangedActionType;
const getActionType = <TPrefix, TActionTypeKeys extends string>(
keys: TActionTypeKeys[]
) => (
prefix: TPrefix
): Record<TActionTypeKeys, [TPrefix, TActionTypeKeys]> => {
return R.pipe(
R.map(k => [k, [prefix, k]] as [TActionTypeKeys, [TPrefix, TActionTypeKeys]]),
R.fromPairs as () => Record<TActionTypeKeys, [TPrefix, TActionTypeKeys]>
)(keys);
}
// const createApiActionType: <TPrefix>(prefix: TPrefix) => Record<"requested" | "completed" | "failed" | "cancelled", [TPrefix, "requested" | "completed" | "failed" | "cancelled"]>
const createApiActionType = <TPrefix>(prefix: TPrefix) => getActionType<TPrefix, ApiActionTypeKeys>(R.keys(ApiActionType))(prefix)
// const createChangedctionType: <TPrefix>(prefix: TPrefix) => Record<"changed", [TPrefix, "changed"]>
const createChangedctionType = <TPrefix>(prefix: TPrefix) => getActionType<TPrefix, ChangedActionTypeKeys>(R.keys(ChangedActionType))(prefix)
是否可以将最后两行简化到下面,而不会丢失结果函数的泛型参数?即保留TPrefix
通用参数,而不要成为前缀类型为unknown
的非通用函数
// const createApiActionType: (prefix: unknown) => Record<"requested" | "completed" | "failed" | "cancelled", [unknown, "requested" | "completed" | "failed" | "cancelled"]>
const createApiActionType = getActionType(R.keys(ApiActionType))
// const createChangedctionType: (prefix: unknown) => Record<"changed", [unknown, "changed"]>
const createChangedctionType = getActionType(R.keys(ChangedActionType))
答案 0 :(得分:2)
给出一个咖喱getActionType
函数声明
declare const getActionType: <TPrefix, TActionTypeKeys extends string>(
keys: TActionTypeKeys[]
) => (
prefix: TPrefix
) => Record<TActionTypeKeys, [TPrefix, TActionTypeKeys]>
,不为内部函数保留通用类型参数TPrefix
,而是使用default unknown
类型实例化。 TS在getActionType
的外部函数签名中寻找一个代码位置来推断其类型实参,然后回退到unknown
,因为TPrefix
在这里未使用。
Example:
declare const apiActionTypeKeys: ApiActionTypeKeys[]
// (prefix: unknown) => Record<ApiActionTypeKeys, [unknown, ChangedActionTypeKeys]>
const createChangedctionType = getActionType(apiActionTypeKeys)
我们可以通过在内部函数上定义TPrefix
来解决此问题。
declare const getActionType: <TActionTypeKeys extends string>(
keys: TActionTypeKeys[]
) => <TPrefix>(prefix: TPrefix) => Record<TActionTypeKeys, [TPrefix, TActionTypeKeys]>
并对其进行测试:
declare const apiActionTypeKeys: ApiActionTypeKeys[]
declare const changedActionTypeKeys: ChangedActionTypeKeys[]
// <TPrefix>(prefix: TPrefix) => Record<ApiActionTypeKeys, [TPrefix, ApiActionTypeKeys]>
const createApiActionType = getActionType(apiActionTypeKeys)
// "requested" | "completed" | "failed" | "cancelled"
const result = createApiActionType("fooPrefix").cancelled[1]
希望,有帮助!