Как мне выразить, что S должен иметь свойство dirty логического типа?

Я пытался задать это ранее в общем (Почему я не могу присвоить U частичному‹T›, когда T расширяет U?), и я думаю, что теперь понимаю, почему S extends {dirty: boolean} неверно (S может быть {dirty: false}, но большинство предложений сводилось к переписыванию функции Итак, как мне переписать эту функцию, чтобы она имела правильную проверку типов и не требовала приведения типов?

import {ActionCreatorWithPreparedPayload} from '@reduxjs/toolkit';
import {assert, pick} from '@helpmedo/util';
import {State, ThunkAction} from '@helpmedo/state';

export const createAsyncUpdateAction = <Arg, S extends {dirty: boolean}, P>(
  updateAction: ActionCreatorWithPreparedPayload<[Arg, Partial<S>], P>,
  selector: (state: State, arg: Arg) => S,
) => (
  arg: Arg,
  update: Partial<S>,
  asyncUpdate: () => Promise<unknown>,
): ThunkAction<unknown> => async (dispatch, getState) => {
  const state = selector(getState(), arg);
  assert(!state.dirty, 'Attempt to modify dirty state');
  const save = pick(state, Object.keys(update));
  dispatch(updateAction(arg, {...update, dirty: true}));
  try {
    const result = await asyncUpdate();
    dispatch(updateAction(arg, {dirty: false} /* as Partial<S> */));
    return result;
  } catch (err) {
    dispatch(updateAction(arg, {...save, dirty: false}));
    throw err;
  }
};

Существующая ошибка Argument of type '{ dirty: false; }' is not assignable to parameter of type 'Partial<S>'.ts(2345) в строке с закомментированным приведением.


person btmorex    schedule 10.02.2020    source источник
comment
Я бы посоветовал вам пройти по этой ссылке github.com/Microsoft/TypeScript/issues/27473   -  person Raj Kumar    schedule 19.02.2020


Ответы (2)


Когда вы объявляете S extends { dirty: boolean }, вы делаете именно то, о чем просите в вопросе — вы объявляете тип S, который должен иметь свойство dirty.

Когда вы объявляете тип как Partial<S>, вы говорите, что все свойства S являются необязательными. Поэтому даже свойство dirty есть.

Просто избавьтесь от частичности S в updateAction, как updateAction: ActionCreatorWithPreparedPayload<[Arg, S], P>, и это должно решить ваши проблемы ????

person SquattingSlavInTracksuit    schedule 13.02.2020

вы делаете S extends { dirty: boolean } правильно. просто замените Partial<S> на S, чтобы исправить, как объясняется SquattingSlavInTracksuit.

person ramachandra s joshi    schedule 20.02.2020