我到底想做什么?

我有一个物体,看起来像这样:

const actions = {
    foo: (state: string, action: {payload: string}) => {},
    bar: (state: string, action: {payload: number}) => {},
    baz: (state: string, action: {payload: boolean}) => {},
    qux: (state: string) => {}
}

我有一个泛型类型,如下所示:

type ActionMapper<T> = T extends (state: any, action: infer Action) => any 
    ? Action extends {payload: infer P} 
        ? (payload: P) => void 
        : VoidFunction 
    : never

The use case for this generic type works like this: enter image description here

如您所见,它从actions.foo()函数中提取action.payload参数的类型.

我希望能够有一个泛型类型,它允许我做相同的事情,但对于整个actions个对象.

我都试了些什么?

我try 创建如下所示的泛型类型:

type ActionsMapper<A> = Record<keyof A, ActionMapper<A[keyof A]>>

but it doesn't exactly do what I was expecting: enter image description here enter image description here

它不是只从actions.foo()中提取参数类型,而是从每个函数中提取参数类型并创建类型联合.我想要的是mappedActions.foo()的类型是(payload: string) => void.

这是我使用的操场:TypeScript Playground.

推荐答案

获得联合类型的原因是Record<keyof A, ActionMapper<A[keyof A]>>:它创建一个具有A的所有键的对象,每个属性的类型ActionMapper应用于A的所有值.但是,您需要的是一个具有A个关键点的对象,每个属性的类型ActionMapper应用于that same个关键点A的值.

您可以使用mapped type来执行此操作:

type ActionsMapper<A> = {
  [K in keyof A]: ActionMapper<A[K]>
}

这将创建想要的对象,其中每个属性的值中使用的键是该属性的键,并且就是那个键.

TypeScript Playground


不同之处在于,在映射类型中,每个值都可以基于该属性的键.对于Record,所有值都是相同的.

已给予:

type ActionsMapper<A> = Record<keyof A, ActionMapper<A[keyof A]>>

简化后的结果如下:

type ARecord<T> = Record<keyof T, T[keyof T]>

这里,keyof TT的所有属性键,T[keyof T]T的所有属性值.这两个keyof表达式是not linked.

我们还可以简化映射类型:

type AMapped<T> = {
  [K in keyof T]: T[K]
}

现在,我们可以将基于Record的类型与自定义映射类型进行比较.你可以很容易地看出其中的区别:

// Record<keyof T, T[keyof T]>
type RecordBased =
  { [K in keyof T]: T[keyof T] }

type Mapped =
  { [K in keyof T]: T[K]       }

Typescript相关问答推荐

如何将http上下文附加到angular中翻译模块发送的请求

使用前的组件渲染状态更新

JS Redux Devtools扩展不工作

TypeScrip表示该类型不可赋值

向NextAuth会话添加除名称、图像和ID之外的更多详细信息

如何在Reaction路由v6.4加载器和操作中获得Auth0访问令牌?

已解决:如何使用值类型限制泛型键?

ANGLING v17 CLI默认设置为独立:延迟加载是否仍需要@NgModule进行路由?

Fp-ts使用任务的最佳方法包装选项

为什么ESLint会抱怨函数调用返回的隐式`any`?

从对象类型描述生成类型

如何在typescript中为this关键字设置上下文

错误TS7030:并非所有代码路径都返回值.";由tsfig.json中的";Strong";:False引起

为什么TypeScrip假定{...省略类型,缺少类型,...选取类型,添加&>}为省略类型,缺少类型?

无法缩小深度嵌套对象props 的范围

打字:注解`是字符串`而不是`布尔`?

TypeScript中的这些条件类型映射方法之间有什么区别?

如何在Typescript 中定义具有相同类型的两个泛型类型的两个字段?

递归类型名称

有没有办法从不同长度的元组的联合中提取带有类型的最后一个元素?