Reputation: 3327
I have created a Typescript DTO, where I want to ensure type safety for a list of strings (which are derived from an enum type.
export class ConnectedUserWithPhotosDTO extends UserWithPhotosDTO {
userTags: keyof User["userTags"][]
constructor(user: User, photos: ResponsePhotoDTO[]) {
super(user, photos)
console.log(user.userTags)
this.userTags = user.userTags;
}
}
The typescript compiler complains about the following error:
Type 'UserTags[]' is not assignable to type 'number | keyof UserTags[][]'.
apparently, the value of userTags
evaluates to
number | keyof UserTags[][]
Here is the enum definition that i am defining.
export enum UserTags {
FITNESS = 'Fitness',
FOURTWENTY_FRIENDLY = '420 Friendly',
MEDITATION = 'Meditation',
DRINKS = 'Drinks',
DOGS = 'Dogs',
CATS = 'Cats',
FASHION = 'Fashion',
WINE_TASTING = 'Wine Tasting',
FOODIE = 'Foodie',
ART = 'Art',
PARTYING = 'Partying',
TRAVELIING = 'Travelling',
GAMING = 'Gaming',
}
Inside the User class the UserTags
is defined as:
@ApiProperty({ enum: UserTags, isArray: true, default: [] })
@Column('enum', { enum: UserTags, array: true, nullable: true, default: [] })
userTags: UserTags[]
how can I define just the type of keyof
for the specific Enum value?
Upvotes: 3
Views: 9588
Reputation: 42188
Your post is a bit confusing because of your use of keyof
. It's unclear whether you want the enum keys "FITNESS"
, etc. or the enum values "Fitness"
, etc.
It's clear based on the code of the User
and your error message that what you are getting when you access user.userTags
is the values. The type of the values is just the enum itself, so you would want
userTags: UserTags[]
just like what you have in the User
. It makes sense that this would match the type in User
since we are setting the userTags
property based on User["userTags"]
.
Let's break down the type keyof User["userTags"][]
that you tried and see what it really means.
User["userTags"]
gives us the userTags
property of the User
type. We can see from your User
code that User["userTags"]
is UserTags[]
. That is an array of the values from the UserTags
enum. So something like ["Fitness", "Fashion"]
.
User["userTags"][]
means that we want an array of these. But it's already an array, so you are now asking for an array of arrays of enum values: UserTags[][]
. Which would be [["Fitness"], ["Fashion", "Foodie"]]
.
keyof User["userTags"][]
means that we now want the keys of that array of arrays: keyof UserTags[][]
. The key of an array is a number
so typescript gives you number | keyof UserTags[][]
. (I'm not sure why it isn't just number
).
Perhaps you were trying to get the keys for the UserTags
enum object? keyof typeof UserTags
will give you the union type "FITNESS" | "FOURTWENTY_FRIENDLY" | "MEDITATION" ...
. But it doesn't seem like that's what you actually want to use. You want the union of the enum values which is just UserTags
.
Upvotes: 1
Reputation: 8295
You can also do something like:
const userTags: User['userTags'];
Upvotes: 2
Reputation: 3593
Assuming that UserTags is enum. Its something like
userTags: Array<keyof typeof UserTags>
Upvotes: 7