interface UserFlags { isDev: boolean; isAdmin: boolean; isMod: boolean; } const flagPositions: FlagPositions<UserFlags> = { isDev: 0, isAdmin: 1, isMod: 2, }; ¿Cómo implementaría FlagPositions para que lleve 1 parámetro genérico a una interfaz con tipo { [name: string]: boolean } y requiera que todas las propiedades de la interfaz estén presentes en la nueva interfaz pero sean del tipo number ?
Probé varios métodos usando keyof pero ninguno funcionó.
Editar: conseguí que esto funcionara después de la publicación, pero me gustaría que fuera una interfaz
type FlagPositions<F> = { [K in keyof Required<F>]: number; };Desea que FlagPositions<T> sea un tipo asignado cuyas claves sean las mismas que keyof T pero cuyos valores sean number . Puedes escribir eso así:
type FlagPositions<T> = { [K in keyof T]: number };Y comprueba que funciona como quieres:
const flagPositions: FlagPositions<UserFlags> = { isDev: 0, isAdmin: 1, isMod: 2, }; Tenga en cuenta que no es necesario restringir T a {[name: string]: boolean} o Record<keyof T, boolean> , pero puede hacerlo si lo desea:
type FlagPositions<T extends Record<keyof T, boolean>> = { [K in keyof T]: number }; declare const oops: FlagPositions<{ a: number }>; // error! // ----------------------------> ~~~~~~~~~~~~~ // Types of property 'a' are incompatible. No puede convertir FlagPositions<T> en una interface porque las interfaces deben tener claves conocidas en el momento de la compilación, y T es genérico y puede tener todo tipo de claves. Pero una vez que tenga el FlagPositions<UserFlags> que tiene claves conocidas (son isDev , isAdmin e isMod ), entonces puede hacer que una interface amplíe eso :
interface UserFlagPositions extends FlagPositions<UserFlags> { } const u: UserFlagPositions = { isDev: 2, isAdmin: 1, isMod: 0 }