Effect CommunityEC
Effect Community13mo ago
3 replies
adrian_g

Restricting Object Keys with TypeScript and Autocomplete

I've got this riddle: I'd like to restrict properties of a generic object argument to a subset of a given set of keys, triggering an error if an object literal passed as arg contains keys outside of that set. I've got this solution:

const RestrictKeys = <T extends string>() =>
<
  U extends { [K in keyof U]: K extends T ? U[K] : never },
>(obj: U): U => obj

const restrictKeys = RestrictKeys<'a' | 'b'>()

export const ok1 = restrictKeys({})
export const ok2 = restrictKeys({ a: 1, b: 'string' })
export const ok3 = restrictKeys({ b: 2 })
export const error = restrictKeys({ a: '1', c: 2 }) // Type 'number' is not assignable to type 'never'


however when typing the keys, I don't get autocomplete for the possible keys (which is essential for the api I'm working on)

The following brings back the auto-complete but I'm not sure if it could cause any unexpected side-effects. And it seems like there should be a simpler way to do this. Any ideas?

const RestrictKeys = <T extends string>() =>
<
  U extends
    & { [K in keyof U]: K extends T ? U[K] : never }
    & Partial<{ [K in T]: U[K] }>,
>(obj: U): U => obj
Was this page helpful?