Вкратце:
Как я могу объявить, используя систему типов 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, который может группировать свои данные и переключать видимость групп предметов. Несмотря на то, что структура входных данных постоянна, имя свойства, содержащего элементы группы, может быть различным в существующих интерфейсах.