Могу ли я расширить тип другим типом?

Рассмотрим следующий тип:

export type Collections = {
  users: User
  business: Business
  permissions: Permissions
  cards: Card
}

// note the Collections[keyof Collections] are just some custom types
// that are objects, but are irrelevant for the question

и скажем, я хочу создать тип, который расширяет вышеупомянутый тип в Record<keyof Collections, unknown>

Я знаю, что typescript недавно представил оператор statisfies, но это полезно только для const не расширения самих типов.

Я знаю форму желаемого типа, т.е.

export type SubCollections = {
  cards: [CardLog, CardActions]
  users: [UserLog]
}

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

const subcollection = <K extends keyof Collections, S extends SubCollections[K]>(
  collection: K,
  sub: S
) => // ...

Это вызывает TypeError:

Тип K нельзя использовать индексный тип SubCollections

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

type SharedKey<K extends keyof Collection> = K extends keyof SubCollections
 ? K
 : never

export const subcollection = <
  K extends keyof Collections,
  S extends SharedKey<K>
>(collection: K, subcol: S) => // ...
// ^ this works!

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

Возможно, я мог бы сказать машинописному тексту, что два типа используют одни и те же ключи?

// something akin to (obviously this is invalid syntax)
export type SubCollections extends Record<keyof Collections, unknown[]> = {
  cards: [CardLog, CardActions]
  users: [UserLog]
}

Какая связь между Card, CardActions и CardLog и User с UserLog?

Bruno Marotta 11.01.2023 13:15

Нет прямого отношения. Может быть любым объектом для любых намерений и целей. Единственная прямая связь заключается в том, что Коллекции и Подколлекции имеют одни и те же ключи (точнее, ключ Подколлекции должен быть ключом Коллекции, но это не точная карта (т.е. некоторые ключи могут быть опущены)

Samuel Hulla 11.01.2023 13:59

Но... эти два типа не используют одни и те же ключи, и поэтому вы получаете сообщение об ошибке... Что, если K в вашем примере означает "бизнес"? Тогда неразумно использовать его как ключ к SubCollections.

vera. 11.01.2023 16:15
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Как заставить Remix работать с Mantine и Cloudflare Pages/Workers
Мне нравится библиотека Mantine Component , но заставить ее работать без проблем с Remix бывает непросто.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
TypeScript против JavaScript
TypeScript против JavaScript
TypeScript vs JavaScript - в чем различия и какой из них выбрать?
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Синхронизация localStorage в масштабах всего приложения с помощью пользовательского реактивного хука useLocalStorage
Не все нужно хранить на стороне сервера. Иногда все, что вам нужно, это постоянное хранилище на стороне клиента для хранения уникальных для клиента...
Что такое ленивая загрузка в Angular и как ее применять
Что такое ленивая загрузка в Angular и как ее применять
Ленивая загрузка - это техника, используемая в Angular для повышения производительности приложения путем загрузки модулей только тогда, когда они...
0
3
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это может помочь?

type Commonkeys<A, B> = keyof A extends infer keyofA ? (keyofA extends keyof B ? keyofA : never) : never;

type AAA = Commonkeys<Collections, SubCollections>;
//  type AAA = "cards" | "users"

const subcollection = <K extends Commonkeys<Collections, SubCollections>, S extends SubCollections[K]>(collection: K, sub: S) => {};

Обновление благодаря Вере:

    const subcollection = <K extends keyof Collections & keyof SubCollections, S extends SubCollections[K]>(
  collection: K,
  sub: S
) => {};

Теперь кажется так просто...

Commonkeys можно записать как keyof A & keyof B.
vera. 11.01.2023 16:15

Вауу. я не знал этого

Romain TAILLANDIER 11.01.2023 16:33

Другие вопросы по теме