RamdaJs с typescript, избегайте ошибок, когда точка свободна

#typescript #ramda.js #pointfree

#typescript #ramda.js #без точек

Вопрос:

 const getColumnsBySection = R.pipe(
    R.filter(c => c.section != null),
    R.groupBy(c => c.section)
  );
  

При использовании point free с RamdaJs, как в этой функции. Я получаю ошибки машинописного текста

  Type 'Dictionary<unknown>' is missing the following properties from type 'readonly unknown[]': length, concat, join, slice, and 18 more.
TS2339: Property 'section' does not exist on type 'unknown'
  

Как вы предполагаете использовать функции без точек, не получая подобных ошибок typescript?

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

1. Нигде нет ничего, что могло бы определить тип, и поэтому никакой тип не может быть выведен… Какая последовательность проходит через этот канал? Т.Е. Какой тип c в ваших предикатах и селекторах? Если функция канала хорошо написана / напечатана (я никогда не использовал ramda), вам нужно только указать этот ввод for c в предикате for filter , и type должен «вытекать» оттуда. Что такое a Dictionary<T> ?

Ответ №1:

Вы можете либо привести функцию к ожидаемым типам, либо вы можете больше полагаться на библиотеку ramda с подобной конструкцией:

 const { anyPass, complement, pipe, propSatisfies, filter, groupBy, prop, isNil, isEmpty } = R

const isBlank = anyPass([isNil, isEmpty]);

const isPresent = complement(isBlank);

const getColumnsBySection = pipe(
  filter(propSatisfies(isPresent, 'section')),
  groupBy(prop('section'))
);

const samples = [
  {section: 'trees', name: 'birch'}, 
  {section: 'vines', name: 'grape'},
  {section: 'trees', name: 'cedar'},
  {section: 'vines', name: 'ivy'},
];

const results = getColumnsBySection(samples);
console.log(results);  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>  

Ответ №2:

Рассмотрим следующий код:

 import * as R from "ramda"

interface Monkey{
  name:string;
}

const p = R.pipe(
  (m: Monkey) => `cheeky-${m.name}`, // `m` can't be inferred, hence type annotation
  (s) => `hello ${s}` // here `s` *can* be inferred
)

console.log(p({name:"monkey"}))
  

Если мы уберем Monkey ввод текста из первой составленной функции, Typescript не сможет знать, что m передаваемый ему аргумент имеет name свойство, и поэтому не сможет правильно ввести аргументы результирующей функции p .

Однако для последующих функций, переданных в pipe , из-за ввода @types/ramda , R.pipe может правильно выводить типизацию этих составных функций из возвращаемого типа предыдущей функции в списке аргументов.

Ссылка на Codesandbox