Home > Enterprise >  Cannot fix error Types of parameters 'r' and 'a' are incompatible
Cannot fix error Types of parameters 'r' and 'a' are incompatible

Time:03-16

I try to replicate this code from this blog, but running into some pretty obscure errors

import { option, identity, apply } from 'fp-ts';
import type { Kind, URIS } from 'fp-ts/HKT';
import { pipe } from 'fp-ts/lib/function';

type OrderId = string;

type OrderState = 'active' | 'deleted';

interface User {
  readonly name: string;
  readonly isActive: boolean;
}

interface OrderHKD<F extends URIS> {
    readonly id: Kind<F, OrderId>;
    readonly issuer: Kind<F, User>;
    readonly date: Kind<F, Date>;
    readonly comment: Kind<F, string>;
    readonly state: Kind<F, OrderState>;
}

type Order = OrderHKD<identity.URI>;
type OrderOption = OrderHKD<option.URI>;

const validateOrder = (inputOrder: OrderOption): option.Option<Order> =>
  pipe(inputOrder, apply.sequenceS(option.Apply));
//                 ^
//                 | here
// Argument of type '<NER extends Record<string, Option<any>>>(r: EnforceNonEmptyRecord<NER>) => Option<{ [K in keyof NER]: [NER[K]] extends [Option<infer A>] ? A : never; }>' is not assignable to parameter of type '(a: OrderOption) => Option<{ [x: string]: any; }>'.
//  Types of parameters 'r' and 'a' are incompatible.
//    Type 'OrderOption' is not assignable to type 'Record<string, Option<any>>'.
//      Index signature for type 'string' is missing in type 'OrderHKD<"Option">'.ts(2345)

CodePudding user response:

I don't know how this code could have worked, since the result of sequenceS has a constraint <NER extends Record<string, Kind<F, any>>>, which cannot be met by an interface due to possible declaration merging (see this TypeScript issue, for example). And that constraint was already present in 2019, which is way before the blog post was written.

Anyhow, you can get the example to work by declaring OrderHKD as a type rather than an interface:

type OrderHKD<F extends URIS> = {
    readonly id: Kind<F, OrderId>;
    readonly issuer: Kind<F, User>;
    readonly date: Kind<F, Date>;
    readonly comment: Kind<F, string>;
    readonly state: Kind<F, OrderState>;
}
  • Related