I have a generic function, which can be simplified to the example below:
type Delegate<Key extends "firstKey" | "secondKey"> = {
key: Key;
deleteMany: (where: { where: { [n in Key]: string } }) => Promise<unknown>;
};
const removeDuplicatesGeneric = <Key extends "firstKey" | "secondKey">(
delegate: Delegate<Key>
) => {
delegate.deleteMany({ where: { [delegate.key]: 'key' } });
};
As key
is of the type Key
, I expect it to not cause issues when passing to where
. TypeScript shows me an error though:
Type '{ [x: string]: string; }' is not assignable to type '{ [n in Key]: string; }'.
Any ideas why [delegate.key]
is interpreted as x: string
instead of x: Key
?
CodePudding user response:
This behavior is by design.
Because string
type is much wider than "firstKey" | "secondKey"
you are getting an error.
In this case, it is ok to use type assertion:
type Delegate<Key extends "firstKey" | "secondKey"> = {
key: Key;
deleteMany: (arg: { where: Record<Key, string> }) => Promise<unknown>;
};
const record = <
Key extends PropertyKey,
Value
>(key: Key, value: Value) =>
({ [key]: value }) as Record<Key, Value>
const removeDuplicatesGeneric = <Key extends "firstKey" | "secondKey">(
delegate: Delegate<Key>
) => {
delegate.deleteMany({ where: record(delegate.key, 'key') });
};