【问题标题】:TypeScript: Remove keys from object by valueTypeScript:按值从对象中删除键
【发布时间】:2021-11-11 10:55:22
【问题描述】:

我有一个以键和函数作为值的对象。现在我想创建一个函数,您只能分配相应键包含回调函数作为最后一个函数参数的键。

回调可能只有一个参数并且返回类型为 void。

interface Events {
  'valid0': (data: string, cb: () => void) => void, // valid
  'valid1': (data: number, cb: (data: string) => void) => void, // valid
  'invalid0': (data: string, cb: () => string) => void, // invalid return type of callback
  'invalid1': (data: string, cb: (string: string, number: number) => void) => void, // invalid number of callback arguments
}

type EventsWithCallback<E> = ???

type testFunction<Events> = (EventName: EventsWithCallback<Events>) => void

我在定义此 EventsWithCallback 类型时遇到问题。随着以下我得到错误:Type 'T[P]' does not satisfy the constraint '(...args: any[]) =&gt; void'。这在某种程度上是合乎逻辑的。我尝试将 T 输入为 Record&lt;string, (...args: any) =&gt; void&gt;,但随后我匹配了所有字符串。

type Last<T extends any[]> = T extends [...any, infer Last] ? Last : any;
type EventsWithCallback<T> = keyof { [P in keyof T as Last<Parameters<T[P]>> extends Function ? P : never]: T[P] };

extends Function 也匹配任何函数和任何类型。

感谢您的任何帮助。我希望这个问题是可以理解的。

【问题讨论】:

  • 为什么第三个无效?和第一个完全一样
  • 是不是因为回调有参数?你还没有说它不能有一个......
  • 我不明白哪种情况应该有效,哪种情况无效
  • 返回类型是字符串而不是void

标签: typescript typescript-generics


【解决方案1】:

这行得通吗? Playground Link

interface Events {
  'valid0': (data: string, cb: () => void) => void, // valid
  'valid1': (data: number, cb: (data: string) => void) => void, // valid
  'invalid0': (data: string, cb: () => string) => void, // invalid return type of callback
  'invalid1': (data: string, cb: (string: string, number: number) => void) => void, // invalid number of callback arguments
}

type Last<T extends any[]> = T extends [...any, infer Last] ? Last : any

type EventsWithCallback<T> = { 
  [P in keyof T]: 
    T[P] extends (...args: infer A) => void // Check if it is a function
      ? Last<A> extends (arg: any) => any // Check if the last parameter is a function with single parameter
        ? ReturnType<Last<A>> extends void // Check if it returns void
          ? P // return the parameter name
          : never
        : never
      : never
}[keyof T]

const testFunction = (eventName: EventsWithCallback<Events>) => {
  eventName = 'invalid0' // error
  eventName = 'invalid1' // error
  eventName = 'valid0'   // no error
  eventName = 'valid1'   // no error
}

【讨论】:

  • 像魅力一样工作。谢谢
猜你喜欢
  • 2019-07-11
  • 1970-01-01
  • 2019-10-19
  • 2014-09-06
  • 1970-01-01
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多