我认为不借助泛型类型参数就不可能引用 userIds 中的确切字符串值:
type UserList<T extends ReadonlyArray<string>> = {
userIds: T
userData: {
[UserId in T[number]]: {
userId: UserId
username: string
}
}
}
您的类型定义必须如下所示:
const a: UserList<['hello']> = {
userIds: ['hello'],
userData: {
hello: {
userId: 'hello',
username: 'username'
}
}
}
如果您不想指定用户 ID 两次(在通用参数内和在实际的UserList 变量内),您可以have to use a wrapper function:
function asUserList<T extends ReadonlyArray<string>>(list: UserList<T>) {
return list;
}
const a = asUserList({
userIds: ['hello'] as const,
userData: {
hello: {
userId: 'hello',
username: 'username'
}
}
})
如果您不使用通用参数,而是尝试在这样的接口中使用 this 类型:
interface UserList {
userIds: string[]
userData: {
[UserId in this['userIds'][number]]: {
userId: UserId
username: string
}
}
}
这是行不通的,因为 this['userIds'] 将始终解析为弱 string[] 类型,而不是允许您根据 userIds 的确切值强键入 userData 的一组特定字符串。