ken
ken

Reputation: 8993

Typing a record of a known type

I have the following interface:

export interface IWatchEventPayload<T> {
  value?: T;
  paths?: IMultiPathUpdates[];
  changed?: IWatchEventChanges<T>;
}

I want the changed property to be a dictionary of properties which are/have undergone change. The idea then from a typing perspective is to ensure that keys of the dictionary are all property of T. Here's how I first attempted it:

export interface IWatchEventChanges<T, K extends keyof T> {
  [prop: K]: [T[K], T[K]];
}

This, I had hoped, would give me the hash property typed and ensure that the "before" and "after" values are also typed. Sadly this lead to an error stating in [prop: K] that prop must be a string or number. In reality it will always be a string so I did the following:

export interface IWatchEventChanges<T, K extends keyof T> {
  [prop: Pick<K, string>]: [T[K], T[K]];
}

But now the original error is retained and now I also get the following on the string type:

Type 'string' does not satisfy the constraint 'keyof K'. Type 'string' is not assignable to type '"toString" | "valueOf"'.

Things are getting messy and I'm a bit stuck. Can anyone help?

Upvotes: 0

Views: 185

Answers (1)

jcalz
jcalz

Reputation: 327964

There's no way to do this as an interface, but you can use a mapped type instead and give it a name via a type alias, which is more flexible. The definition you want is probably something like:

export type IWatchEventChanges<T> = {
  [K in keyof T]: [T[K], T[K]];
}

Hope that helps; good luck!

Upvotes: 2

Related Questions