Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

184
Visualizações
Why type `Function` doesn't work when typing a higher-order function parameter that accepts a function?

I want to type a function that takes as inputs:

  1. array
  2. a function for filtering logic (predicate function)

In JavaScript, the following works as expected:

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 ] 

However, in TypeScript it throws an error:

const myFilter = (func: Function, arr: any[]): any[] => arr.filter(func)
//                                                                  ^
//                                                        (parameter) func: Function
//                                                        No overload matches this call.

Although typing func as any solves the error, I still want to know:

  1. how come that type Function doesn't work?
  2. what would be a proper type for func parameter?
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Function refers to the js function class used to create functions from a string.

Instead use the following syntax: func: (current: T, i: number, arr: T[]) => boolean. This type creates a callback type that Array.prototype.filter accepts since it mimmicks its parameters and return type.

Using generics you can have a HOF function that accepts any type:

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]));

If you don't want to use generics and restrict the function to a specific type, simply remove <T> and replace T with the desired type.

about 4 years ago · Juan Pablo Isaza Relatório

0

With generic you can write, look at the second parameter func defined like a callback. Array<T> - this is referred as generic type, where T is the generic type supplied while calling the function, whatever you supply would become T. Sp it could be number or string or integer like that, if you pass number which your example is sending T would te number.

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);

You can even constraint the type like this. So now you will have to always pass array of numbers but not anything else.

const myFilter = <T extends number>(arr: Array<T>, func: (value: T) => any) => {
   return arr.filter(func)
}

With your specific question without using generic it can be simply written like this,

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);
about 4 years ago · Juan Pablo Isaza Relatório

0

In order to maximize the utility of your function, you can write multiple overloads:

  • one that accepts a generic type guard predicate function
  • one that accepts a standard boolean predicate function for array.filter

By writing an overload for the type guard version, you can infer the guarded type in the predicate and get a narrowed array in the case that the original array/tuple is homogeneous (see example 2).

TS Playground

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]
}

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda