Home > Software engineering >  How can I define a type that maps keys to a generic of that key, e.g. Record<K, SomeGeneric<ke
How can I define a type that maps keys to a generic of that key, e.g. Record<K, SomeGeneric<ke

Time:09-08

I'm trying to do something that seems like it should be simple, but I'm at a total loss for how to accomplish it. I'll try to summarise it succinctly here and elaborate on the actual use case below.

I want to create a enter image description here enter image description here

And I can supply that to the Diff, so that SprocketChanges picks up the type for that property automatically:

enter image description here

But I'm still having to manually redefine the keys found in Sprocket. I'd rather define it generically with the Socket interface as the single source of truth on keys and types, meaning something like this:

type SprocketChanges = Record<K extends keyof Sprocket, Diff<SprocketValueType<K>>;

or this:

type SprocketChanges = Record<keyof Sprocket, Diff<SprocketValueType<key>>;

But neither of these are legal code. The second is even wishing for a magic value key that doesn't exist. Both surface a ts(2304) error:

enter image description here

enter image description here

What type definition will work? How can I define this SprocketChanges interface, and map Sprocket's keys to a Diff<T> with that key's value?

CodePudding user response:

The solution part type Changes<T> = {[K in keyof T] : Diff<T[K]>} means map a type that for every key the object has, create a property with a generic Diff<T> type that has T[K] as type argument which means typeof Object[Key]

interface Sprocket {
  name: string;
  fobbed: boolean;
  cycles: number;
}

interface Diff<T> {
  previous: T;
  current: T;
}


type Changes<T> = {[K in keyof T] : Diff<T[K]>}

type SproketChanges = Changes<Sprocket>

Playground

  • Related