Как продлить неизменяемость хелпера? - PullRequest
0 голосов
/ 29 сентября 2019

Я пытаюсь выяснить, каков правильный способ расширения помощника неизменности .

Вот что у меня есть:

import imupdate, {CustomCommands, Spec, extend} from 'immutability-helper';

extend<ReadonlyArray<any>>('$removeWhere', function<T>(func: ((v:T, i:number) => boolean), array: ReadonlyArray<T>) {
    return array.filter((el,idx) => !func(el,idx));
})


interface ExtraCommands<T> extends CustomCommands<object> {
    $removeWhere: (v:T, i:number) => boolean,
}

export default function immutableUpdate<TObject, TCommands extends ExtraCommands<TObject>>($spec: Spec<TObject, TCommands>) {
    return (object: TObject) => imupdate(object, $spec);
}

ИЯ пытаюсь назвать это так:

TypeScript усекает сообщение об ошибке с помощью ...4 more..., поэтому я не могу понять, подхватывает ли он $removeWhereили нет.

$removeWhere это должен принимать функцию, которая возвращает логическое значение, я не знаю, почему он говорит мне:

Type 'boolean 'нельзя назначить типу' fetchZones_zones '.

Определение TypeScript довольно интенсивно.Я подозреваю, что способ определения TCommands и ExtraCommands не совсем верен.


Я думаю, что он попадает в индексатор ArraySpec и впоследствии ((v: T) => T) вместо моего $removeWhere определения.


Я исправил проблему усечения и подправил несколько вещей.

Код теперь:

import imupdate, {CustomCommands, Spec, extend} from 'immutability-helper';

type CallbackFn<T> = (value: T, index: number) => boolean;

extend<ReadonlyArray<any>>('$removeWhere', function <T>(func: CallbackFn<T>, array: ReadonlyArray<T>) {
    return array.filter((el, idx) => !func(el, idx));
})

export type UpdateSpec<TRoot> = Spec<TRoot, CustomCommands<{
    $removeWhere: CallbackFn<TRoot>,
}>>;

function immutableUpdate<TObject>($spec: UpdateSpec<TObject>): (o: TObject) => TObject;
function immutableUpdate<TObject>($spec: UpdateSpec<TObject>, object: TObject): TObject;
function immutableUpdate<TObject>($spec: UpdateSpec<TObject>, object?: TObject) {
    return object === undefined
        ? (object: TObject) => imupdate(object, $spec)
        : imupdate(object, $spec);
}

export default immutableUpdate;

Использование:

const x = imupdate<fetchZones>({
    zones: {$removeWhere: (z:fetchZones_zones) => z.id == zone.id}
});

Ошибка проявляется как:

src/client/components/routes/data/ZoneEditor.tsx:298:56 - error TS2345: Argument of type '{ zones: { $removeWhere: (z: fetchZones_zones) => boolean; }; }' is not assignable to parameter of type 'Spec<fetchZones, CustomCommands<{ $removeWhere: CallbackFn<fetchZones>; }>>'.
  Type '{ zones: { $removeWhere: (z: fetchZones_zones) => boolean; }; }' is not assignable to type '{ readonly zones?: { $removeWhere: CallbackFn<fetchZones>; } | { $push: fetchZones_zones[]; } | { $unshift: fetchZones_zones[]; } | { $splice: ([number, (number | undefined)?] | [number, number, ...fetchZones_zones[]])[]; } | { [index: string]: Spec<fetchZones_zones, CustomCommands<{ $removeWhere: CallbackFn<fetchZones>; }>>; } | { $set: readonly fetchZones_zones[]; } | { $apply: (v: readonly fetchZones_zones[]) => readonly fetchZones_zones[]; } | ((v: readonly fetchZones_zones[]) => readonly fetchZones_zones[]) | undefined; }'.
    Types of property 'zones' are incompatible.
      Type '{ $removeWhere: (z: fetchZones_zones) => boolean; }' is not assignable to type '{ $removeWhere: CallbackFn<fetchZones>; } | { $push: fetchZones_zones[]; } | { $unshift: fetchZones_zones[]; } | { $splice: ([number, (number | 
undefined)?] | [number, number, ...fetchZones_zones[]])[]; } | { [index: string]: Spec<fetchZones_zones, CustomCommands<{ $removeWhere: CallbackFn<fetchZones>; }>>; } | { $set: readonly fetchZones_zones[]; } | { $apply: (v: readonly fetchZones_zones[]) => readonly fetchZones_zones[]; } | ((v: readonly fetchZones_zones[]) => readonly fetchZones_zones[]) | undefined'.
        Type '{ $removeWhere: (z: fetchZones_zones) => boolean; }' is not assignable to type '{ [index: string]: Spec<fetchZones_zones, CustomCommands<{ $removeWhere: CallbackFn<fetchZones>; }>>; }'.
          Property '$removeWhere' is incompatible with index signature.
            Type '(z: fetchZones_zones) => boolean' is not assignable to type 'Spec<fetchZones_zones, CustomCommands<{ $removeWhere: CallbackFn<fetchZones>; }>>'.
              Type '(z: fetchZones_zones) => boolean' is not assignable to type '(v: fetchZones_zones) => fetchZones_zones'.
                Type 'boolean' is not assignable to type 'fetchZones_zones'.

298                         const x = imupdate<fetchZones>({
                                                           ~
299                             zones: {$removeWhere: (z:fetchZones_zones) => z.id == zone.id}
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
300                         });
    ~~~~~~~~~~~~~~~~~~~~~~~~~

Из ошибки видно, что она набирает { readonly zones?: { $removeWhere: CallbackFn<fetchZones>; }, но CallbackFnзанимает fetchZones вместо fetchZones_zones[], как и другие.Мне нужно выяснить, как добавить новую команду в ArraySpec вместо корневого объекта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...