Reputation: 1964
I'm trying to get an object's values and make them as keys for the interface. Here's what I do:
const obj = {
a: 'foo',
b: 'bar',
} as const;
type A<T extends object, K extends keyof T = keyof T> = {
[x: string]: T[K];
}[number];
// this one fails with:
// Type 'T[string]' is not assignable to type 'symbol'
type B<T extends object> = {
[K in A<T>]: any;
};
// even if I do something like this, it still fails with the same error.
type C<T extends typeof obj = typeof obj> = {
[K in A<T>]: any;
};
// this one works.
type D = {
[K in A<typeof obj>]: any;
};
// this works, yay.
const a: D = {
foo: 1,
bar: 1,
};
I've never faced anything like this before, can somebody explain why this does not work? (or if there are any better ways to write it)?
Upvotes: 0
Views: 42
Reputation: 37938
The error says that it is not guaranteed that values of passed type are valid to be keys in a new type (Type 'T[string]' is not assignable to type 'string | number | symbol'
). This can be fixed with appropriate generic constraint (e.g. T extends Record<PropertyKey, PropertyKey>
instead of T extends object
)
type ValuesAsKeys<T extends Record<PropertyKey, PropertyKey>> =
Record<T[keyof T], any>;
const a: ValuesAsKeys<typeof obj> = {
foo: 1,
bar: 1,
};
Upvotes: 1
Reputation: 3140
You can extract the values from your object with the following type
type Values<T extends object> = T[keyof T]
Upvotes: 1