我想輸入一個作為輸入的函式:
- 大批
- 過濾邏輯的函式(謂詞函式)
在 JavaScript 中,以下內容按預期作業:
const myFilter = (func, arr) => arr.filter(func)
const myArr = [1, 2, 3, 4, 5, 6]
const res = myFilter(x => x > 3, myArr)
console.log(res) // => [ 4, 5, 6 ]
但是,在 TypeScript 中它會引發錯誤:
const myFilter = (func: Function, arr: any[]): any[] => arr.filter(func)
// ^
// (parameter) func: Function
// No overload matches this call.
雖然輸入funcasany解決了錯誤,但我仍然想知道:
- 為什么那種型別
Function不起作用? - 什么是合適的
func引數型別?
uj5u.com熱心網友回復:
Function指的是用于從字串創建函式的js函式類。
而是使用以下語法:func: (current: T, i: number, arr: T[]) => boolean. 這種型別創建了一個回呼型別,Array.prototype.filter因為它模仿了它的引數和回傳型別,所以它接受。
使用泛型,您可以擁有一個接受任何型別的 HOF 函式:
function myFilter<T>(func: (current: T, i: number, arr: T[]) => boolean, arr: T[]): T[] {
return arr.filter(func);
}
console.log(myFilter((v) => v % 2 === 0, [1, 2, 3, 4, 5, 6]));
如果您不想使用泛型并將函式限制為特定型別,只需洗掉<T>并替換T為所需型別即可。
uj5u.com熱心網友回復:
使用泛型您可以撰寫,查看func定義為回呼的第二個引數。Array<T>- 這被稱為泛型型別,其中 T 是呼叫函式時提供的泛型型別,無論您提供什么都將成為 T. Sp 它可以是數字或字串或整數,如果您傳遞您的示例發送的數字 T 將電話號碼。
const myFilter = <T,>(arr: Array<T>, func: (value: T) => any) => {
return arr.filter(func);
}
const myArr = [1, 2, 3, 4, 5, 6];
const res = myFilter(myArr, x => x > 3);
console.log(res);
你甚至可以像這樣約束型別。所以現在你必須總是傳遞數字陣列,而不是其他任何東西。
const myFilter = <T extends number>(arr: Array<T>, func: (value: T) => any) => {
return arr.filter(func)
}
在不使用泛型的情況下使用您的特定問題,可以這樣簡單地撰寫,
const myFilter = (arr: Array<any>, func: (value: number) => any) => {
return arr.filter(func)
}
const myArr = [1, 2, 3, 4, 5, 6]
const res = myFilter(myArr, x => x > 3)
console.log(res);
uj5u.com熱心網友回復:
為了最大化您的函式的效用,您可以撰寫多個多載:
- 一個接受通用型別保護謂詞函式的函式
- 一個接受標準布爾謂詞函式的
array.filter
通過為型別保護版本撰寫多載,您可以在謂詞中推斷出受保護的型別,并在原始陣列/元組是同構的情況下獲得一個縮小的陣列(參見示例 2)。
TS游樂場
type ArrayItemPredicate<U, T extends U> = (
value: U,
index: number,
array: readonly U[],
) => value is T;
function myFilter <U, T extends U, A extends readonly U[]>(
arr: A,
filterPredicate: ArrayItemPredicate<U, T>,
): T[];
function myFilter <A extends readonly unknown[]>(
arr: A,
filterPredicate: Parameters<A['filter']>[0],
): A[number][];
function myFilter <
U,
T extends U,
A extends readonly U[],
Predicate extends ArrayItemPredicate<U, T> | Parameters<A['filter']>[0],
>(arr: A, filterPredicate: Predicate) {
return arr.filter(filterPredicate);
}
{ // example 1: from your question
const arr = [1, 2, 3, 4, 5, 6];
const predicate = (n: number) => n > 3;
const res = myFilter(arr, predicate); // number[]
console.log(res); // [4, 5, 6]
}
{ // example 2: filter to keep only numbers
const arr = [1, 'a', 2, 'b', 3, 4, 'c', 'd', 'e', 'f', 5, 6];
const predicate = (value: string | number): value is number => typeof value === 'number';
const res = myFilter(arr, predicate); // number[]
console.log(res); // [1, 2, 3, 4, 5, 6]
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/463746.html
標籤:javascript 打字稿 功能 ecmascript-6 函数式编程
