簡體   English   中英

TypeScript:為什么Parameters泛型接受錯誤的參數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM