#is there a way to dynamically enforce unique keys of an object in an array on a type level?

11 messages · Page 1 of 1 (latest)

rare ocean
#

I have asked this months ago, and im curious to see if since then anyone found a solution for this issue.

My thinking is the following:
Lets say you have a function chooseKeys that takes an object as a first arguemnt, and then you would have after that from 1 to keys.length arguments passed. those arguemnts would be enforced on a type leve that would not be possible to have repeated keys. looking for this on a type level, dont care about the runtime implementation. is this possible at all?

manic glacierBOT
#
itstheandre#0

Preview:```ts
type A = {
name: string
age: string
from: string
banana: string
move: string
}

type Keys = keyof A

declare function chooseKeys<
T extends Record<string, string>,
TKeys extends keyof T,
TRest extends Array<keyof T>

(features: T, key: TKeys, ...rest: TRest): T
...```

zenith lance
#

Here is one solution using a recursive type.

manic glacierBOT
#
nonspicyburrito#0

Preview:```ts
type ValidateKeys<
K extends unknown[],
F extends unknown[] = []

= K extends [...F, infer H, ...unknown[]]
? H extends F[number]
? never
: ValidateKeys<K, [...F, H]>
: K

declare function chooseKeys<
T,
K extends [keyof T, ...(keyo
...```

zenith lance
#

Although tbh, not sure if the extra safety is worth it.

rare ocean
#

hey @zenith lance this is a great solution. the only "problem" i se, is that even tho the types fail on repeated types, the autocomplete gives you the repeated option key. ideallty in this case it would remove it entirely

zenith lance
#

You can generate a union of all the allowed tuples, but that will explode in numbers if the object has many keys.

zenith lance
#

Another question prompted me for this solution:

manic glacierBOT
#
nonspicyburrito#0

Preview:```ts
type ValidateKeys<T, K> = K extends never
? K
: K extends readonly [...infer H, unknown]
? [...H, Exclude<keyof T, H[number]>]
: [keyof T]

declare function chooseKeys<T extends object, const K>(obj: T, ...keys: ValidateKeys<T, K>): void

declare const obj: {
...```

static sandal
#

Hiw can I ask my own question? IWhat is the rule here?

subtle void