TypeScript-type med egenskaper på et objekt som inneholder en spesifikk type
Jeg vil lage en generisk type CompatibleProp<T, U> som vil løse seg til en strengtype som inneholder alle egenskapene til T som har verdier av typen U.
Eksempel på hva jeg ønsker å oppnå:
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
Er dette mulig å oppnå med TypeScript 2.8 betingede typer? Jeg har prøvd noen kombinasjoner, men finner ikke den rette.
Svar #1
Selvfølgelig kan du gjøre dette med betingede typer og en ekstra typeforespørsel
type PropCompatible<T, TProp> = { [P in keyof T] : T[P] extends TProp ? P : never}[keyof T]
Rediger
Mens typen ovenfor fungerer godt for å få en union av nøkler av en bestemt type, har den i konteksten av en generisk funksjon ulempen at kompilatoren ikke kan følge med på at egenskaps-tilgangen vil være av den gitte egenskapstypen. For å oppnå dette må vi uttrykke begrensningen om at vi kun tar nøkler av en bestemt feltstype på en annen måte. Vi kan gjøre dette ved å bruke en ekstra typeparameter K for nøkkelen og kreve at for K er typen til feltet i T av den gitte typen (Date for eksempel)
function getDate<T extends Record<K, Date>, K extends string>(t: T, k: K): Date {
return t[k];
}
