Deep Omit с машинописью - PullRequest
       2

Deep Omit с машинописью

5 голосов
/ 05 апреля 2019

Можно ли поддерживать покрытие типа для функции, которая глубоко удаляет все экземпляры ключа в объекте?

Моя функция выглядит следующим образом.

function omitDeep<T extends object>(obj: T, key: string): TWithoutProvidedKey {
  return JSON.parse(
    JSON.stringify(obj),
    (key: string, value: any) => key === "__typename" ? undefined : value
  );
}

Есть ли способ сделать TWithoutProvidedKey реальностью?

1 Ответ

6 голосов
/ 05 апреля 2019

Это легко сделать, вам просто нужно использовать сопоставленные типы, чтобы восстановить свойства:

type Primitive = string | Function | number | boolean | Symbol | undefined | null 
type DeepOmitHelper<T, K extends keyof T> = {
    [P in K]: //extra level of indirection needed to trigger homomorhic behavior 
        T[P] extends infer TP ? // distribute over unions
        TP extends Primitive ? TP : // leave primitives and functions alone
        TP extends any[] ? DeepOmitArray<TP, K> : // Array special handling
        DeepOmit<TP, K> 
        : never
}
type DeepOmit<T, K> = T extends Primitive ? T : DeepOmitHelper<T,Exclude<keyof T, K>> 

type DeepOmitArray<T extends any[], K> = {
    [P in keyof T]: DeepOmit<T[P], K>
}
type Input =  {
    __typename: string,
    a: string,
    nested: {
        __typename: string,
        b: string
    }
    nestedArray: Array<{
        __typename: string,
        b: string
    }>
    nestedTuple: [{
        __typename: string,
        b: string
    }]
}

type InputWithoutKey = DeepOmit<Input, '__typename'>

let s: InputWithoutKey = {
    a: "",
    nested: {
        b:""
    },
    nestedArray: [
        {b: ""}
    ],
    nestedTuple: [
        { b: ""},
    ]
}

Просто предостережение, это работает на 3.4, обработка отображенных типов в массивах и кортежах недавно изменилась, поэтому в зависимости от версии вам может понадобиться обрабатывать массивы как особый случай.

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