thopaw
thopaw

Reputation: 4044

ramda has typescript error when using filter

I want to use ramda in my typescript project but I am a little bit confused about the usage.

Ramda is complaining about filter within a pipe with an error I do not understand.

Here is my reduced sample:

import * as R from 'ramda';

// Dummy types for Stackoverflow
export enum EventLabel {
  started = 'started',
  answered = 'answered',
  checked = 'checked',
}
type TimestampedEventType = {
  label: EventLabel;
  timestamp: number;
};

export interface Timerange {
  start?: number;
  end?: number;
  durationInMillis?: number;
}

type TimerangeReduceResult = { result: Timerange[]; current?: Timerange };

export const findStartEndPairs = (events: TimestampedEventType[]): Timerange[] =>
  R.pipe(
    R.filter<TimestampedEventType>(({ label }) => [EventLabel.started, EventLabel.answered].includes(label)),
    R.tap((filtered) => console.log(filtered, 'filtered')), // <=== this fixes the typing !?!?
    R.reduce<TimestampedEventType, TimerangeReduceResult>(
      ({ result, current }, next): TimerangeReduceResult => {
        if (next.label === EventLabel.started) {
          return {
            result,
            current: {
              start: next.timestamp,
            },
          };
        }
        if (next.label === EventLabel.answered && !!current.start) {
          return {
            result: [
              ...result,
              { start: current.start, end: next.timestamp, durationInMillis: next.timestamp - current.start },
            ],
          };
        }
        return { result };
      },
      { result: [] },
    ),
    R.prop('result'),
  )(events);

When I omit the line

R.tap((filtered) => console.log(filtered, 'filtered')), // <=== this fixes the typing

typescript is complaining about the following error

Type '{}' is missing the following properties from type 'Timerange[]': length, pop, push, concat, and 28 more.ts(2740) No overload matches this call. The last overload gave the following error. Argument of type 'FilterOnceApplied' is not assignable to parameter of type '(x0: unknown, x1: unknown, x2: unknown) => readonly TimestampedEventType[]'. Type 'TimestampedEventType[] | Dictionary' is not assignable to type 'readonly TimestampedEventType[]'. Type 'Dictionary' is missing the following properties from type 'readonly TimestampedEventType[]': length, concat, join, slice, and 18 more.ts(2769)

Do anyone have a clue how to fix this?

Upvotes: 0

Views: 1030

Answers (1)

Hitmands
Hitmands

Reputation: 14179

This works fine with [email protected]: Playground

import * as R from 'ramda';

export enum EventLabel {
  started = 'started',
  answered = 'answered',
  checked = 'checked',
}
type TimestampedEventType = {
  label: EventLabel;
  timestamp: number;
};

export interface Timerange {
  start?: number;
  end?: number;
  durationInMillis?: number;
}

type TimerangeReduceResult = { result: Timerange[]; last?: Timerange };

const isEitherStartedOrAnswered = R.propSatisfies(
    R.either(R.equals(EventLabel.started), R.equals(EventLabel.answered)),
    'label',
);

const reducer = R.reduce<TimestampedEventType, TimerangeReduceResult>(
    ({ result, last }, item) => {
    if (item.label === EventLabel.started) {
        return {
        result,
        current: {
          start: item.timestamp,
        },
      };
    }

    if (item.label === EventLabel.answered && last?.start) {
        return {
        result: [
          ...result,
          { start: last.start, end: item.timestamp, durationInMillis: item.timestamp - last.start },
        ],
      };
    }
    return { result };
  },    
  { result: [] },
);

export const findStartEndPairs = R.pipe<
  TimestampedEventType[], 
  TimestampedEventType[],
  TimerangeReduceResult,
  Timerange[]
>(
  R.filter(isEitherStartedOrAnswered),
  reducer,
  R.prop('result'),
);

Upvotes: 2

Related Questions