Reputation: 5002
I want to make a generic type CompatibleProp<T, U>
which would resolve to a string type containing all the properties of T
that hold values of type U
.
Example of what I want to achieve:
class C {
a: number;
b: string;
c: Date;
}
type DatePropOfC = PropCompatible<C, Date>; // "c"
type NumberOrStringPropOfC = PropCompatible<C, number | string>; // "a" | "b"
type AnyPropOfC = PropCompatible<C, any>; // same as keyof C
Is this possible to achieve with TypeScript 2.8 conditional types? I've tried a few combinations can't find the right one.
Upvotes: 3
Views: 3356
Reputation: 249466
Sure you can do this with conditional types and a extra type query
type PropCompatible<T, TProp> = { [P in keyof T] : T[P] extends TProp ? P : never}[keyof T]
Edit
While the above type works well for getting a union of keys of a certain type, in the context of a generic function it has the disadvantage that the compiler can't follow the fact that the property access will be of the given property type. To get this behavior we need to state the constraint that we only take keys of a given filed type in a different way. We can do this using an extra type parameter K
for the key and mandate that for K
the type of the field in T
is of the given type (Date
for example)
function getDate<T extends Record<K, Date>, K extends string>(t: T, k: K): Date {
return t[k];
}
Upvotes: 3