[英]TypeScript: Why is Parameters generic accepting incorrect arguments?
我有一個為參數定義類型的函數。 參數是key
,它是指定接口IBook
的鍵,而value
的類型應對應於接口中的特定鍵。 即,如果key === 'id'
則唯一可接受的value
類型應該是number
。
當我想創建另一個函數以僅將onChange
事件的參數傳遞給第一個函數時,就會出現問題。 為了避免再次聲明函數參數,我使用了Parameters
泛型,但是它的行為似乎不正確。 檢查以下用法。
interface IBook {
id: number;
title: string;
isPromoted?: boolean;
}
export const editBook = <K extends keyof Required<IBook>>(
key: K,
value: Required<IBook>[K],
) => ({
type: 'EDIT_BOOK',
payload: { key, value },
});
const onChange = (...args: Parameters<typeof editBook>) => {
dispatch(editBook(...args));
};
editBook('id', 'some string'); // string not accepted here, shows error
onChange('id', 'some string'); // no error here
editBook('id', true); // boolean not accepted here, shows error
onChange('id', true); // no error here
如果我使用原始函數editBook
,那么value
的鍵入正確-它只是對應於key
類型的那個。 如果我使用另一個,則顯示錯誤。 但是,如果我使用包裝函數onChange
,則value
參數接受IBook
存在的任何類型。
有什么辦法可以解決這個問題?
當使用Parameters
您不會捕獲原始函數的類型參數,而typescript將僅使用約束條件來查找對該類型參數的任何引用,因此onChange
的簽名實際上只是:
(key: keyof IBook, value: Required<IBook>[keyof IBook]) => void
可以解決:
(key: "id" | "title" | "isPromoted", value: string | number | boolean) => void
允許無效呼叫。
不幸的是,沒有明確的方法來捕獲類型參數並將其轉發給新函數。 從3.4開始,有一個隱式的方法,使用此處描述的管道函數
function pipe<A extends any[], B, C>(ab: (...args: A) => B, bc: (b: B) => C): (...args: A) => C {
return (...args: A) => bc(ab(...args));
}
function dispatch<T extends { type: string }>(action: T): void {
}
const onChange = pipe(editBook, dispatch); // generic type parameter preserved
editBook('id', 'some string'); // string not accepted here, shows error
onChange('id', 'some string'); // error now
editBook('id', true); // boolean not accepted here, shows error
onChange('id', true); // error now
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.