Typescript: объединение двух типов / интерфейсов и поддержание правильности всех обобщений - PullRequest
6 голосов
/ 24 апреля 2020

Я хочу объединить два типа, а также сохранить действительные дженерики. например

Тип 1

interface Request<P extends core.Params = core.ParamsDictionary, ResBody = any, ReqBody = any, ReqQuery = core.Query> extends core.Request<P, ResBody, ReqBody, ReqQuery> { }

Тип 2

type Auth = {
  user: User
}

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

Сейчас я просто объединяю их, но потом я не могу использовать дженерики типа Request.

В настоящее время я просто объединяю эти два.

export type Merge<FirstType, SecondType> = Omit<FirstType, keyof SecondType> & SecondType;

Конечно, я могу сделать все это вручную, но этот случай повторяется в моем проекте, я хочу использовать вспомогательный метод, который может сделать это для меня. Например,

MergeWithGenerics<Request, Body>

Где новый тип хранит все дженерики первого аргумента.

Я не знаю, возможно ли это или нет, но было бы действительно здорово, если бы кто-то мог помочь мне с этим.

Ответы [ 2 ]

0 голосов
/ 04 мая 2020

Возможно, вы могли бы использовать фрагмент - при условии, что вы используете VSCode или аналогичный.

Используя следующий фрагмент VSCode, вы можете ввести «mgen» и завершить табуляцию (ctrl + space), а затем tab в имени фрагмента. Каждый раз, когда вы набираете sh tab, курсор будет перемещаться к следующим переменным позициям.

фрагменты. json

{

"Merged Generic": {
    "prefix": "mgen",
    "body": [
        "export type Merge<$1, $2> = Omit<$1, keyof $2> & $2;",
    ],
    "description": "shorthand for defining merged generics"
}

} enter image description here

В вашем случае вам, вероятно, понадобятся 3 или 4 переменные.

0 голосов
/ 04 мая 2020

Вы не можете передать тип generic c (без параметров) другому типу generi c.

interface Generic<P> { }
type Id<T> = T
type G = Id<Generic>; // Generic type 'Generic<P>' requires 1 type argument(s).(2314)

При этом ваше определение Merge выглядит довольно симпатичным хорошая стенография для того, что вы пытаетесь сделать. Merge<Request<Params, ResBody, ReqBody, Query> & Auth> не кажется намного больше, чем RequestWithAuth<Params, ResBody, ReqBody, Query>.

Вариант предложения от @leonardfactory может также немного упростить:

 type ExtendedRequest<Extension, P, TRes, TReq, TQuery> = Merge<Request<P, TRes, TReq, TQuery>, Extension>
...