#How to prevent keyof generic from being a union type of keys through distributive inference ?

7 messages · Page 1 of 1 (latest)

delicate kite
#

Codesandbox link : https://codesandbox.io/p/sandbox/typescript-distributive-union-inference-problem-g8m3z7?file=%2Fsrc%2Findex.ts%3A35%2C1

I have a problem with the use of generic K = keyof T and it's corresponding type T[K] inside interface FeatureKey<T, K>. K is becoming union type of different keys through distribution and I want K inside FeatureKey interface to always be only one key.
My code got complex and I feel lost on how to demonstrate my problem with fewer code. I'm sorry for that, I will keep working on it.

I didn't get any error (line 56) before using FeatureGroup with union to FeatureKey inside the property key$ of FeatureObject. It is only after adding this new interface that I realized there was already a problem before.
The recursive use of type Feature<T> inside FeatureKey<T, K> is definitely what is making my example complex and making the error raise now. Otherwise I would not even see the problem coming from K becoming a union type.

I read multiple stackoverflow posts on union type distribution and keyof problems for the past days. I even read this post https://stackoverflow.com/questions/50639496/is-there-a-way-to-prevent-union-types-in-typescript which defines a NoUnion type but I don't understand how it could apply to my code.
I know I can use assertions to remove the error but I'm afraid my type definition is not correct and could be better, more safe.

To sum up my problem using the error raised on line 56:
I want to keep Observable<FeatureKey<State, 'camera'> | FeatureKey<State, 'objects'>>.
I don't want Observable<FeatureKey<State, 'camera' | 'objects'>> because then it's not valid types, and the compiler tries to compare it to FeatureGroup.

CodeSandbox is an online editor tailored for web applications.

royal fjord
#

i suspect i could help with this but i was having trouble grappling with your example code earlier. i know you said you'd keep working on it, but if you can come up with a simpler example (ideally not involving rxjs, since it doesn't seem fundamentally implicated with your problem) then i could take another look

snow steeple
#
type FeatureKeys<T extends object> = {
  [K in keyof T & string]: FeatureKey<T, K>;
}[keyof T & string];

export interface FeatureObject<T extends object> {
  key$: Observable<FeatureGroup<T> | FeatureKeys<T>>;
}
delicate kite
#

oh damn I was about to go to sleep but this is looking like what I wasn't able to do and feels right. I knew this syntax would help but wasn't able to apply it. I'm going to test that in my project quickly

delicate kite
delicate kite
snow steeple
#

👍 yw