#limit generics to specific types?

21 messages · Page 1 of 1 (latest)

forest arrow
#

I've got this example of a generic method that's swapping out values on an object.

Let's say I wanted swapProperty to only work on strings, or only work on numbers. Is there a way to add that constraint on the generic definitions?

mighty notchBOT
#
claudekennilol#0

Preview:```ts
class Foo {
foo: string = "some string"
bar: number = 123
fooz: string = "another string"
baz: number = 321
}

function swapProperty<T, K extends keyof T>(
obj: T,
prop: K,
value: T[K]
) {
obj[prop] = value
}

const foo = new Foo()
...```

feral stag
#

sure, just gotta move stuff around so you can get the constraints in the right place:

mighty notchBOT
#
that_guy977#0

Preview:```ts
class Foo {
foo: string = "some string"
bar: number = 123
fooz: string = "another string"
baz: number = 321
}

function swapProperty<
K extends PropertyKey,
T extends Record<K, string>

(obj: T, prop: K, value: T[K]) {
obj[prop] = value
...```

feral stag
#

you could also use the validator pattern, but that's kind overkill for something as (comparatively) simple as this

forest arrow
#

Awesome, thanks 👍. I'll toy around with this and hopefully I can make it work for my real (more complicated) case 😅

elfin crest
#

When swapping from one type to another, you could always Omit the key, then add it back

feral stag
#

that's swapping values, not types

forest arrow
# mighty notch

Hm, this example seems to make intellisense dumber (at least in ts playground) and not suggest anything for the second parameter. The analysis works as expected but the goal was more about intellisense :/

feral stag
#

i think the relation would have to be the other way around for that (as it was originally)

#

not sure ts would accept a constraint like that

forest arrow
#

Dang. So no "best of both worlds" option here?

mighty notchBOT
#
that_guy977#0

Preview:```ts
class Foo {
foo: string = "some string"
bar: number = 123
fooz: string = "another string"
baz: number = 321
}

type KeysOfType<
T extends {},
V

= keyof T extends infer K extends keyof T
? K extends K
? T[K] extends V
? K
: never
: never
: never
...```

feral stag
#

quite a bit more verbose

#

im kinda tired right now so it might be reduceable or i might be missing something but it's possible, at least

forest arrow
#

😍 It's gorgeous!

#

Yeah that works for my real case as well, thanks a ton. It would've taken me far longer to get there without your help

#

!solved

#
type KeysOfType<T, TProp> = { [P in keyof T]: T[P] extends TProp ? P : never }[keyof T];

This looks to be a simplified version. It seems to work just as well

feral stag
#

ah yeah that's much more concise

slow hazel
#
type KeysOfType<T, TProp> = keyof { [P in keyof T as (T[P] extends TProp ? P : never )]: never }