在使用泛型函式引數創建函式時,有沒有辦法防止引數的錯誤利用?
感知的標準案例將函式型別為內部的“任何函式”:
const rip = <T extends (...args: any[]) => any>(f: T) => f('invalid');
rip((a: number) => a.toFixed(2)); // oops
Givenany是一個 boo-doo 并使所有內容都變得雙變數,我嘗試了以下方法,但它仍然沒有考慮引數的數量:
const rip2 = <T extends (...args: readonly never[]) => unknown>(f: T) => f();
rip2((a: number) => a.toFixed(2)); // oops again
以前可能有人問過這個問題,但對我來說搜索它很困難(圍繞“通用”和“高階”的類似主題太多)。
為了避免 XY 問題,問題的根源是撰寫一個函式,該函式用檢查包裝函式。這是我最初打算如何撰寫它:
declare const check: () => boolean;
const checked = <T extends (...args: any[]) => any>(f: T): (...args: Parameters<T>) =>
ReturnType<T> | undefined => (...args) => {
if (check()) return;
return f(...args); // `f('invalid')` would not cause an error
};
const g = checked((a: number) => a.toFixed(2));
它也有同樣的問題。在內部,函式是(...args: any[]) => any,因此沒有檢查。與上面類似,更嚴格的約束并不能完全解決問題(沒有引數仍然有效),readonly會導致錯誤,并且需要強制轉換:
declare const check: () => boolean;
const checked = <T extends (...args: /* readonly */ never[]) => unknown>(f: T): (...args:
Parameters<T>) => ReturnType<T> | undefined => (...args) => {
if (check()) return;
return f(...args) as ReturnType<T>; // `f()` would not cause an error
};
const g = checked((a: number) => a.toFixed(2));
uj5u.com熱心網友回復:
通過更具體的型別(即為 args 和回傳型別創建單獨的泛型型別,而不是從單個函式型別推斷它們),如果為函式提供了不正確的引數,TypeScript 能夠更好地推斷出問題所在。
declare const check: () => boolean;
const checked = <A extends any[], R>(f: (...args: A) => R): (...args: A) =>
R | undefined => (...args) => {
if (check()) return;
return f(...args);
};
const g = checked((a: number) => a.toFixed(2));
游樂場鏈接
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/462378.html
標籤:打字稿
