Typescript 中的类构造函数重载

问题描述 投票:0回答:1

我正在开发一个类

PlaybackControl
,我用它来创建两个 HTMLElement:

  1. PlaybackControlButton: HTMLButtonElement
  2. PlaybackControlMenu: HTMLDivElement

现在,要初始化类对象,我需要三个参数:

  1. videoPlayer: HTMLVideoElement
  2. playbackRates: PlaybackRates
  3. options: PlaybackControlOptions

地点:

type Shortcuts = Record<string, { key: string, value: string }>
type PlaybackRates = string[]

interface ShortcutsEnabled {
  enableShortcuts: true
  shortcuts: Shortcuts
}

interface ShortcutsDisabled {
  enableShortcuts: false
}

interface DefaultOptions extends ShortcutsEnabled {}

type PlaybackControlOptions = DefaultOptions | ShortcutsDisabled

此外,我对所有这些都有默认值,

  1. videoPlayer
    默认为
    document.querySelector('video') as HTMLVideoElement
  2. playbackRates
    默认为静态属性
    PlaybackControl.DEFAULT_PLAYBACK_RATES
  3. options
    默认为
    { enableShortcuts: true, shortcuts: PlaybackControl.DEFAULT_SHORTCUTS }

现在,我想创建一个在所有情况下都适用的重载构造函数:

  1. 没有通过任何参数
  2. 传递的参数的任意组合 任何未给出的值都应回退到默认值,

最后,

videoPlayer: HTMLVideoElement
是我想存储为类属性的唯一参数,其余两个只是我只想在构造函数中调用一些函数的参数(因为我以后不再使用它们)。

目前我写的构造函数是:

constructor (videoPlayer?: HTMLVideoElement, playbackRates: PlaybackRates = PlaybackControl.DEFAULT_PLAYBACK_RATES, options: PlaybackControlOptions = { enableShortcuts: true, shortcuts: PlaybackControl.DEFAULT_SHORTCUTS })

虽然这确实允许我在没有任何参数的情况下进行初始化,但当我尝试这样做时会失败:

new PlaybackControl({ enableShortcuts: false })

并且 VSCode 显示错误:

Object literal may only specify known properties, and 'enableShortcuts' does not exist in type 'HTMLVideoElement'.

虽然我确实了解根本问题(我猜),但我无法解决这个问题。 任何帮助都是适当的。

javascript typescript class constructor constructor-overloading
1个回答
0
投票

当我尝试这样做时,它失败了:

new PlaybackControl({ enableShortcuts: false })

我不会尝试重载构造函数来接受这一点。它需要检查第一个参数是 dom 元素还是选项对象,然后将参数混入各自的变量中。这会导致相当丑陋的代码和复杂的类型签名。

相反,要跳过传递前两个参数,请为它们传递

undefined
,然后将选项对象作为第三个参数传递:

new PlaybackControl(undefined, undefined, { enableShortcuts: false })

如果这是一种常见用法,请考虑更改构造函数以仅接受一个对象参数,以便您可以调用

new PlaybackControl({ options: { enableShortcuts: false } })
© www.soinside.com 2019 - 2024. All rights reserved.