Решена проблема с типом, но не понятно, что именно было сделано

#typescript

#typescript

Вопрос:

Я столкнулся с очень распространенной ошибкой типа cid => cid , как показано ниже.

 import * as _ from 'lodash';
export const func1 = _.wrap(
  _.memoize(() => _.debounce(func2, 1500), cid => cid),
  (func: Function, cid: number) => func(cid)(cid),
);
 
 Argument of type '(cid: Parameters<T>[0]) => Parameters<T>[0]' is not assignable to parameter of type '() => any'.ts(2345)
 

Ошибка довольно проста, но было трудно что-то сделать, потому что у меня были проблемы с пониманием исходного кода. Мне удалось исправить ошибку, как показано ниже:

 import * as _ from 'lodash';
export const func1 = _.wrap(
  _.memoize(() => _.debounce(func2, 1500), ((cid: any) => cid) as any),
  (func: Function, cid: number) => func(cid)(cid),
);
 

Я рад, что наткнулся на обходной путь, но я хотел бы знать, что именно исправило ситуацию.
Моими основными препятствиями являются:

  1. Проблемы с пониманием того, что именно соответствует чему. Это cid => cid тот (cid: Parameters<T>[0]) => Parameters<T>[0] тип, который был неправильным?
  2. Parameters<T>[0] рассматривается как тип, но [] для меня это ново.
  3. Какой синтаксис используется func(cid)(cid) ? Похоже ли это func(cid) на другую функцию?

Комментарии:

1. Какую версию Lodash вы используете?

2. @tmhao2005 lodash@4.17.20 и @types/lodash@4.14.165

Ответ №1:

Я выяснил, что в вашей реализации была тривиальная проблема, описанная выше следующим образом:

Вот memoize подпись:

 <T extends (...args: any) => any>(func: T, resolver?: (...args: Parameters<T>) => any): T amp; MemoizedFunction;
 

Давайте посмотрим resolver , как 2-й аргумент будет принимать параметр функции, аргумент которого является аргументом T которого () => _.debounce(func2, 1500) .

() => _.debounce(func2, 1500) это функция, у которой нет никаких параметров, что означает resolver , что у вас тоже не должно быть параметров.

Короче говоря, правильная реализация должна быть (на основе определенного типа, который также может быть неправильным, если ваш код выполняется хорошо):

 export const func1 = _.wrap(
  _.memoize(() => _.debounce(func2, 1500), () => {}), // the 2nd param would take the argument of the 1st param `() => _.debounce(func2, 1500)`
  // or if you wish to have parameter for 2nd argument, you should add for the 1st one too
  // _.memoize((id) => _.debounce(func2, 1500), (id) => id),
  (func: Function, cid: number) => func(cid)(cid),
);

 

Что касается вашего вопроса о том, что такое func(cid)(cid) ? Поскольку func задано как Function type, поэтому его просто можно вызвать дважды ( func(cid) возвращает другое Function , затем оно было вызвано в другой раз func(cid)(cid) )