Есть ли способ сделать рекурсивный частичный с новым членом в Typescript - PullRequest
0 голосов
/ 03 апреля 2020

Резюме

У меня есть эти type. Однако я не могу понять, как сделать рекурсивное частичное с новым членом.

Пример

PartialWithNewMember:

type PartialWithNewMember<T> = {
  [P in keyof T]?: T[P];
} & { newMember: boolean }

RecursivePartial:

type RecursivePartial<T> = {
  [P in keyof T]?: RecursivePartial<T[P]>;
};

Попытка решения

Это самое близкое, что я мог получить, который работает, но выглядит как хак. ?‍♂️

type RecursivePartialWithNewMembers<T> =
  | ({
      [P in keyof T]?: RecursivePartialWithNewMembers<T[P]>;
    } & { [key: string]: any })
  | T;

Мой вариант использования позволяет потребителю избыточного Как магазин, который я использую, чтобы передать initialState с дополнительными и опущенными свойствами. Однако мне бы хотелось, чтобы все свойства, которые соответствуют ключам, имели правильные типы.

Редактировать: Добавлен пример

Вот пример того, что я пытаюсь сделать.

Я хочу создать тип Store. Это может иметь свойства добавленные и пропущенные при сохранении правильного набора существующих свойств.

Пример

createStore функция, экспортированная из библиотеки NPM пакет

interface Market {
  locale: string;
}

interface Tenant {
  id: string;
}

interface Customer {
  id: string;
  hasProduct?: boolean;
}

interface Product {
  id: string;
  title: string;
  price: number;
}

interface State {
  market: Market;
  tenant: Tenant;
  customer: Customer;
  product: Product;
}

// Export a function that can be called from other packages and will return a redux-like store with state (of type State with props added or omitted)
export const createStore = (initialState: RecursivePartialWithNewMembers<State>, actions: RecursivePartialWithNewMembers<Actions>) => { ... };

createStore функция, импортированная из веб-приложения первого клиента

import createStore from '@somePackage';

// `customer` property is omitted; `product.relatedProducts` property is added;
const initialState = {
  market: {
    id: 'US'
  },
  tenant: {
    id: 'first',
  },
  product: {
    id: '',
    title: '',
    price: 0,
    relatedProducts: []
  }
};

const store = createStore(initialState, actions);

createStore функция, импортированная из веб-приложения второго клиента

import createStore from '@somePackage';

// `product.price` property is omitted; `customer.devices` property is added;
const initialState = {
  market: {
    id: '',
    locale:
  },
  tenant: {
    id: ''
  },
  customer: {
    id: '',
    hasProduct: false,
    devices: []
  },
  product: {
    id: '',
    title: ''
  }
};

const store = createStore(initialState, actions);
...