【问题标题】:Typescript generic argument to const value常量值的打字稿通用参数
【发布时间】:2019-10-27 08:15:08
【问题描述】:

是否可以有一个接受泛型参数的 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))

【问题讨论】:

标签: typescript


【解决方案1】:

给定一个柯里化的getActionType 函数声明

declare const getActionType: <TPrefix, TActionTypeKeys extends string>(
  keys: TActionTypeKeys[]
) => (
    prefix: TPrefix
  ) => Record<TActionTypeKeys, [TPrefix, TActionTypeKeys]>

,泛型类型参数TPrefix不会为内部函数保留,而是用default unknown类型实例化。 TS 在getActionType 的外部函数签名中查找代码位置以推断其类型参数并回退到unknown,因为这里没有使用TPrefixExample:

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]

Full example

希望,它会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-15
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-06
    • 2018-01-10
    • 2019-05-06
    • 2022-12-05
    相关资源
    最近更新 更多