无法修复错误参数类型 'r' 和 'a' 不兼容

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

我尝试从 this blog 复制这段代码,但是 运行 出现了一些非常模糊的错误

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)

我不知道这段代码是如何工作的,因为 sequenceS 的结果有一个约束 <NER extends Record<string, Kind<F, any>>>,由于可能的声明合并,接口无法满足该约束(参见 this TypeScript issue,例如)。而且这种限制在 2019 年就已经存在,那是在撰写博客 post 之前。

无论如何,您可以通过将 OrderHKD 声明为 type 而不是 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>;
}