我正在开发一个类
PlaybackControl
,我用它来创建两个 HTMLElement:
PlaybackControlButton: HTMLButtonElement
PlaybackControlMenu: HTMLDivElement
现在,要初始化类对象,我需要三个参数:
videoPlayer: HTMLVideoElement
playbackRates: PlaybackRates
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
此外,我对所有这些都有默认值,
videoPlayer
默认为 document.querySelector('video') as HTMLVideoElement
playbackRates
默认为静态属性 PlaybackControl.DEFAULT_PLAYBACK_RATES
options
默认为 { enableShortcuts: true, shortcuts: PlaybackControl.DEFAULT_SHORTCUTS }
现在,我想创建一个在所有情况下都适用的重载构造函数:
最后,
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'.
虽然我确实了解根本问题(我猜),但我无法解决这个问题。 任何帮助都是适当的。
当我尝试这样做时,它失败了:
new PlaybackControl({ enableShortcuts: false })
我不会尝试重载构造函数来接受这一点。它需要检查第一个参数是 dom 元素还是选项对象,然后将参数混入各自的变量中。这会导致相当丑陋的代码和复杂的类型签名。
相反,要跳过传递前两个参数,请为它们传递
undefined
,然后将选项对象作为第三个参数传递:
new PlaybackControl(undefined, undefined, { enableShortcuts: false })
如果这是一种常见用法,请考虑更改构造函数以仅接受一个对象参数,以便您可以调用
new PlaybackControl({ options: { enableShortcuts: false } })