Как представить группу данных как универсальный c интерфейс Typescript - PullRequest
0 голосов
/ 26 марта 2020

Вкратце:

Как я могу объявить, используя систему типов Typescript, универсальный c интерфейс, который принимает в качестве параметров типа

  • тип G группы (все свойства, принадлежащие группе)
  • тип I элемента в группе (все свойства элемента, которого в группе несколько)
  • тип N свойства в G, которое имеет в качестве значения G[N] массив элементов I[] для группы

и имеет результирующий тип интерфейса, являющийся группой G с свойство N набрано для массива элементов I , а также включает все остальные свойства G в результирующий тип.



Что я пробовал до сих пор

Редакция № 2 (успех)

После ознакомления с типами вычисляемых индексов (правильное имя?) И их ограничениями я пришел к такому подходу:

type GroupOfItems<Group, Item, GroupOn extends keyof Group> = {
    [n in GroupOn]: Item[];
}
type A = {a: any, children: B[]};
type B = {b: number};

let obj: GroupOfItems<A, B, 'children'> & Omit<A, 'children'>;

Я использую тип объединения, чтобы объединить универсальный интерфейс «group» c и «другие» свойства, в результате чего ully проверенный тип объекта структуры, которую я хочу. Проверьте это на этой площадке

Редакция # 1

Первый ответ с предупреждением о синтаксической ошибке. Он предоставил действительный интерфейс с 3 параметрами типа. Однако в результирующем типе отсутствуют какие-либо групповые свойства , отличные , кроме массива элементов.

Моя следующая попытка, которая, как представляется, недопустима Typescript (см. plays ) :

type GroupOfItems<Group, Item, GroupProp extends keyof Group> = {
    [OtherProp in keyof Omit<Group, GroupProp>]: Group[OtherProp];
    [n in GroupProp]: Item[];
}

Моя наивная первая попытка:


interface GroupOfItems<GroupType, ItemType, NameOfItemsProp extends keyof G> {
    [key: NameOfItemsProp]: ItemType[];
}

Однако, как вы можете видеть в этой игровой площадке TS , компилятор Typescript не рад этому, и я не могу придумать, как обойти это.

Конкретное использование этой конструкции

Предполагая следующие типы

    interface Movie {  // An example Item
        id: number,
        title: string,
        releaseYear: number,
        // ... more movie properties
    }

    interface MovieList {  // An example group
        id: number,
        description: string,        
        // ... more list properties
        movies: Movie[], // This property holds the item array
    }

определены, я хочу, чтобы полученный интерфейс GroupOfItems<MovieList, Movie, 'movies'> был совместим с объектом со структурой, подобной

{ 
    id: 0,
    description: 'A collection of funny movies'
    totalRuntimeInSecs: 9815,
    // ... other list properties
    movies: [
        {
            id: 0,
            title: 'Blazing Saddles',
            releaseYear: 1974,
            // ... 
        }
    ]
}

Однако я также хочу конкретный тип GroupOfItems<Playlist, Song, 'songs'> (при условии Playlist и Song определены) для совместимости с

{
    playlistId: 0,
    playlistName: string,
    playlistDescription: string,
    //... more playlist props
    songs: Song[]  // This property holds the item array
}

Мотивация для вопроса

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

1 Ответ

1 голос
/ 26 марта 2020

Это то, что вы ищете?

interface Movie {  // An example Item
    id: number,
    title: string,
    releaseYear: number,
    // ... more movie properties
}

interface MovieList {  // An example group
    id: number,
    description: string,
    // ... more list properties
    movies: Movie[], // This property holds the item array
}

type GroupOfItems<Group, Item, GroupOn extends keyof Group> = {
    [key in GroupOn]: Item[];
}

const obj: GroupOfItems<MovieList, Movie, 'movies'> = {
    id: 0,
    description: 'A collection of funny movies',
    movies: [
        {
            id: 0,
            title: 'Blazing Saddles',
            releaseYear: 1974,
        }
    ]
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...