我想输入一个数组,这样数组中唯一允许的值就是对象列表中某个键的值.
原则上,我知道这可以这样做:
const page1 = {
videoTitles: ['someTitle', 'otherTitle'],
} as const
const page2 = {
videoTitles: ['title', 'goodTitle'],
} as const
const allVideos = [...page1.videoTitles, ...page2.videoTitles]
// As desired, the if statement raises an error because 'badTitle' isn't in either of the lists
if (allVideos.includes('badTitle')) {
console.log('Found!')
}
然而,我想要做的是为对象赋予一个类型并获得相同的行为,但我就是想不出如何做到这一点.以下是我想要的大致内容:
type PageWithVideos = { readonly videoTitles: readonly string[] }
const page1: PageWithVideos = {
videoTitles: ['someTitle', 'otherTitle'],
} as const
const page2: PageWithVideos = {
videoTitles: ['title', 'goodTitle'],
} as const
const allTitles = [...page1.videoTitles, ...page2.videoTitles]
// Now, however, I don't get the same error. allTitles is just a string[]
if (allTitles .includes('badTitle')) {
console.log('Found!')
}
我发现我真的可以用这样的东西force它:
type PageWithVideos<T extends string> = { readonly videoTitles: readonly T[] }
const page1: PageWithVideos<'someTitle' | 'otherTitle'> = {
videoTitles: ['someTitle', 'otherTitle'],
} as const
const page2: PageWithVideos<'title' | 'goodTitle'> = {
videoTitles: ['title', 'goodTitle'],
} as const
const allVideos = [...page1.videoTitles, ...page2.videoTitles] as const
// I'm getting the error again (which is good), but this is a little silly
if (allVideos.includes('badTitle')) {
console.log('Found!')
}
但我更希望不必重复列表中的每个标题和通用名称.如有任何 idea ,我们将不胜感激!
编辑-使用 case :
建立一个只限FE的纪录片组合网站.这些视频托管在外部视频平台(YouTube、Vimeo)上,并嵌入到网站中.
比如说,客户有100个视频.这些视频有大约7种不同的观看方式.客户希望能够在每个屏幕上 Select 显示哪些视频以及显示的顺序.许多视频将出现在多个屏幕上.
我想提供一个解决方案,其中客户可以将Video
个对象添加到大约videos.ts
个文件中.添加视频时,会判断这些值的类型.然后,我希望客户转到另一个文件(recetWork.ts
),并添加他想要在该页面上显示的视频的标题.但我真正想要的是recentWork.ts
上的标题列表与videos.ts
上所有视频名称的列表进行类型判断.
// videos.ts
export const videos: Video[] = [{
title: 'someTitle',
...
}, {
title: 'title',
...
}]
// recentWorks.ts
export const recentWorkPageInfo = {
videoTitles: ['title', 'someTitle'], // type-checked against `title` key from videos
...
}
解决方案:@ghybs得到了它!
// videos.ts
export const videos = [{
title: 'someTitle',
...
}, {
title: 'title',
...
}] as const satisfies Video[]
// recentWorks.ts
import { videos } from '../videos'
type PageInfo = {
videoTitles: (typeof videos)[number]['title'][]
}
export const recentWorkPageInfo = {
videoTitles: ['title', 'someTitle'], // type-checked!!
...
}