网站搜索

TypeScript 中 kwargs 的等价物


我想创建一个 Typescript 类 RepeatLoader,它的作用是接收一个函数,这个函数用于加载一些数据,并将在 while 循环中运行,直到一个回调(用于检查某个条件是否为真)停止它。

目前看起来大致如下:

class RepeatLoader() {
    loadDataFunc: () => void,
    shouldLoadCallback: () => boolean
    
    constructor(loadDataFunc, shouldLoadCallback) {
        this.loadDataFunc = loadDataFunc;
        this.shouldLoadCallback = shouldLoadCallback
    }
    
    startRunning() {
        while(this.shouldLoadCallback()) {
             this.loadDataFunc()
             sleep(3000)
        }
    }
}

我希望能够向 loadDataFunc 传递动态参数。类似于一个 loadDataParams 对象,它可以通过构造函数或 startRunning 函数传递。

来自 Python 的话,这将是 **kwargs 的教材示例。但我不确定如何在 TypeScript 中做到这一点。有人有建议吗?

提前谢谢你。

答案#1

你可以使用泛型:

class RepeatLoader<A extends unknown[]> {
    loadDataFunc: (...args: A) => void
    shouldLoadCallback: () => boolean

    constructor(loadDataFunc: (...args: A) => void, shouldLoadCallback: () => boolean) {
        this.loadDataFunc = loadDataFunc
        this.shouldLoadCallback = shouldLoadCallback
    }

    startRunning(...args: A) {
        while (this.shouldLoadCallback()) {
            this.loadDataFunc(...args)
            sleep(3000)
        }
    }
}

// Usage:

const shouldLoadCallback = (): boolean => { /* ... */ }

const foo = new RepeatLoader(
  (x: number, y: number) => console.log(x + y),
  shouldLoadCallback
)
foo.startRunning(1, 2)

const bar = new RepeatLoader(
  ({x, y}: {x: number; y: number}) => console.log(x + y),
  shouldLoadCallback
)
bar.startRunning({x: 1, y: 2})
  • `A extends unknown[]` 意味着 `A` 需要是某种数组,这允许我们使用 `(...args: A)`
  • (...args: A) 就像 Python 的 *args
  • 你能接近 Python 的 **kwargs 的最接近方式是像上面例子中的 bar 那样使用:使用一个单独的对象参数

如果你只想让 loadDataFunc 接受一个参数,你可以这样做:

class RepeatLoader<T> {
    loadDataFunc: (arg: T) => void
    shouldLoadCallback: () => boolean

    constructor(loadDataFunc: (arg: T) => void, shouldLoadCallback: () => boolean) {
        this.loadDataFunc = loadDataFunc
        this.shouldLoadCallback = shouldLoadCallback
    }

    startRunning(arg: T) {
        while (this.shouldLoadCallback()) {
            this.loadDataFunc(arg)
            sleep(3000)
        }
    }
}

但是第一种方法更通用。