Reputation: 7119
Consider the following type:
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
and let's say I want to create a type that extends the aforementioned type in Record<keyof Collections, unknown>
I know typescript recently introduced the statisfies
operator, but that is only useful for const
not extending the types themelves.
I know the shape of my desired type, i.e.
export type SubCollections = {
cards: [CardLog, CardActions]
users: [UserLog]
}
this works, however it's not very practical, because when I want to use a function
const subcollection = <K extends keyof Collections, S extends SubCollections[K]>(
collection: K,
sub: S
) => // ...
This throws a TypeError:
Type
K
cannot be used index typeSubCollections
Which obviously I understand why it happens. I know I could create an artificial type-narrower i.e.
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!
But this still feels rather clumsy if I had to individually narrow the argument in every single use-case.
Is there perhaps a way I could tell typescript, that the two types share the same keys?
// something akin to (obviously this is invalid syntax)
export type SubCollections extends Record<keyof Collections, unknown[]> = {
cards: [CardLog, CardActions]
users: [UserLog]
}
Upvotes: 0
Views: 332
Reputation: 2015
Is this might helps ?
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) => {};
Update thanks to vera :
const subcollection = <K extends keyof Collections & keyof SubCollections, S extends SubCollections[K]>(
collection: K,
sub: S
) => {};
Seems so simple now ...
Upvotes: 1