英文:
Typescript reference 'this' type of an object
问题
考虑以下类型:
type UserList = {
userIds: string[]
userData: {
[UserId in UserList['userIds'][number]]: {
userId: UserId
username: string
}
}
}
有了这个,我想告诉TypeScript编译器两件事:
userData
的键必须存在于userIds
中userId
字段必须等于相同条目的键
我觉得我需要某种 this
或 self
关键字,而不是 UserList
。
英文:
Consider the following type:
type UserList = {
userIds: string[]
userData: {
[UserId in UserList['userIds'][number]]: {
userId: UserId
username: string
}
}
}
with that I want to tell TypeScript compiler two things:
userData
keys must exist inuserIds
userId
field must be equal to the key of the same entry
I feel that I need some kind of this
or self
keyword instead of UserList
答案1
得分: 0
我不相信可以在不使用通用类型参数的情况下引用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
变量内),您必须使用包装函数:
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
的特定字符串集合。
英文:
I don't believe it's possible to refer to the exact string values inside userIds
without resorting to using a generic type parameter:
type UserList<T extends ReadonlyArray<string>> = {
userIds: T
userData: {
[UserId in T[number]]: {
userId: UserId
username: string
}
}
}
And your type definition would have to look as follows:
const a: UserList<['hello']> = {
userIds: ['hello'],
userData: {
hello: {
userId: 'hello',
username: 'username'
}
}
}
If you don't want to specify the user IDs twice (inside the generic parameter and inside the actual UserList
variable), you 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'
}
}
})
If you don't use a generic parameter and instead try to use the this
type inside an interface like this:
interface UserList {
userIds: string[]
userData: {
[UserId in this['userIds'][number]]: {
userId: UserId
username: string
}
}
}
It wouldn't work because this['userIds']
would always resolve to the weak string[]
type, not a specific set of strings that would allow you to strongly type userData
based on the exact value of userIds
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论