在 TypeScript 中,泛型被一般化為字串
我有一個通用函數,可以簡化為下面的範例:
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' } });
};
由於 key 屬於 Key,我預期它在傳遞到哪裡時不會造成問題。不過 TypeScript 顯示一個錯誤:
Type '{ [x: string]: string; }' is not assignable to type '{ [n in Key]: string; }'.
有人知道為什麼 [delegate.key] 會被解讀為 x: string 而不是 x: Key 嗎?
答案#1
這種行為是設計使然。由於 string 類型比 "firstKey" | "secondKey" 廣泛得多,因此你會遇到錯誤。
在這種情況下,使用類型斷言是可以的:
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') });
};
遊樂場
