typescript - 如何将方法参数类型限制为父对象的键?
问题描述
您可以在以下代码片段中看到,我必须为 GIF 手动键入所有可能的字符串选项。但我想一定有更好的方法来实现这一点。任何人都可以帮助我吗?
type GIF =
| 'dmg_high'
| 'dmg_mid'
| 'dmg_sustained'
| 'quest_invite'
| 'quest_start'
| 'quest_finish'
| 'error'
const tenor = {
TENOR_URL: 'https://tenor.com/view/',
GIFS: {
dmg_high: ['damage-thats-alot-of-damage-jon-tron-gif-13054497'],
dmg_mid: ['hanginthere-damage-gif-19763661'],
dmg_sustained: [
'ugh-guys-im-hit-jason-david-frank-red-zeo-ranger-tommy-oliver-power-rangers-zeo-gif-19564332',
],
quest_invite: ['gandalf-looking-for-adventure-gif-13515313'],
quest_start: [
'adventure-lotr-hobbit-lord-of-gif-5730296',
'lord-of-the-rings-ian-mc-kellen-gandalf-prepare-for-battle-prepare-gif-4879285',
],
quest_finish: ['clapping-clap-applause-lotr-lord-gif-5730286'],
error: 'debugging-we-bare-bears-panda-grizzly-polar-bear-gif-7268856',
},
gif(key: GIF) {
if (!this.GIFS[key]) {
return this.TENOR_URL + this.GIFS.error
}
return this.TENOR_URL + this.GIFS[key][0]
},
}
export default tenor
解决方案
对您的代码所做的最少更改可能是定义gifs
为一个单独的常量,并使用keyof typeof gifs
.
const gifs = {
dmg_high: ['a'],
dmg_mid: ['b'],
dmg_sustained: ['c'],
quest_invite: ['d'],
quest_start: ['e','f'],
quest_finish: ['g'],
error: 'h',
}
type GIF = keyof typeof gifs
然而...
在打字稿中,通常最好从类型接口开始,然后将常量创建为这些类型。所以你应该把这些键写两次。一旦进入界面(这是您的模板,确保您拥有正确格式的所有数据),然后进入数据(检查以确保其格式正确)。
这可以确保您的运行时数据与您的预期类型相匹配,这就是打字稿的重点。
这可能看起来像这样:
type GIF =
| 'dmg_high'
| 'dmg_mid'
| 'dmg_sustained'
| 'quest_invite'
| 'quest_start'
| 'quest_finish'
interface Tenor {
TENOR_URL: string
GIFS: { [key in GIF]: string[] } & { error: string }
gif(key: GIF): string
}
这也修复了一个错误。很明显这error
是特殊的,因为它是单个字符串,而不是像其他字符串那样的字符串数组。
把那个钥匙留在外面GIF
不是一个有效的钥匙。这很重要,因为如果error
传入,那么您的函数将执行this.GIFS['error'][0]
返回错误 gif 字符串的第一个字母,而不是整个字符串,这不是您想要的。所以我们不允许error
进入,GIF
但我们确实在 gifs 对象的类型中将它作为正确的类型,因此它仍然可以被声明和访问。
现在您可以将对象创建为该类型,并从对运行时数据的类型检查中受益:
const tenor: Tenor = {
TENOR_URL: 'https://tenor.com/view/',
GIFS: {
dmg_high: ['a'],
dmg_mid: ['b'],
dmg_sustained: ['c'],
quest_invite: ['d'],
quest_start: ['e','f'],
quest_finish: ['g'],
error: 'h',
},
gif(key: GIF) {
if (!this.GIFS[key]) {
return this.TENOR_URL + this.GIFS.error
}
return this.TENOR_URL + this.GIFS[key][0]
},
}
推荐阅读
- javascript - 当我尝试在网格布局中添加组件时,我的代码不起作用
- angular - 在 Angular rxjs 中订阅
- r - 传单图像未在 Shinyapp 中显示
- flutter - 如何制作迷你有状态小部件以随时间添加新点?
- security - 在 Misp 中找到 IoC
- c# - 如何从 /mnt/secret-store/DataAccessSettings--ConnectionSettings--ConnectionString 读取机密
- google-pagespeed - 在不同国家运行 PageSpeed Insight Api
- javascript - 如何使用 Bootstrap modals 和 jQuery 实现可重用的确认对话框?
- visual-studio-code - 为什么 Neovim 不突出显示整个语法?
- javascript - 使用拆分函数创建动态函数