I'm trying to make an interface for my realm Database using typescript.
Basically I have an automation bot and I want to keep track of how people are using it and how much. For that I made some schemas that I want to add into an internal database and be able to recover information later.
So I made an interface for this realm database. The idea is that I provide what entity I want to add or recover and Typescript would give me the entity object as return type.
I defined the models of the entity objects as following:
export type AllEntitiesModel = {
copypastas: {
group: string;
requester: string;
};
googleSearches: {
group: string;
requester: string;
query: string;
};
};
And I've made an enum containing all my entity types:
export enum EntityTypes {
COPYPASTAS = 'copypastas',
GOOGLESEARCHES = 'googleSearches',
}
If I create a type like
type CopypastaModel = AllEntitiesModel[EntityTypes.COPYPASTAS];
It works, it knows that the CopypastaModel should be
copypastas: {
group: string;
requester: string;
};
What I'm trying to accomplish is to have a function that can do this but from the type of the argument I'm passing to it.
I would have a function with ideally this signature
function getAllEntities(entityType: EntityTypes) => AllEntitiesModel[entityType]
where this entityType
is an argument that I pass to the function. In other words, I want typscript to know that if I call getAllEntities(EntityTypes.COPYPASTAS)
I'm expecting it to return an object with type AllEntitiesModel.copypasta
and if i call getAllEntities(EntityTypes.GOOGLESEARCHES)
I'm expecting it to return an object with type AllEntitiesModel.googleSearch
I've tried a lot of things with no success. I have dug through the typescript documentation and found nothing like that. Any help is appreciated ;)
CodePudding user response:
You'll need to define generic type parameter restricted to allowed keys:
declare function getAllEntities<T extends keyof AllEntitiesModel>(entityType: T): AllEntitiesModel[T]
This allows Typescript to narrow return type according to provided key.
Here we use type argument inference — that is, we want the compiler to set the value of
T
for us automatically based on the type of the argument we pass in
So for example in call getAllEntities(EntityTypes.COPYPASTAS)
the type of T
will be inferred as EntityTypes.COPYPASTAS
(which is "copypastas"
) and return value type will be resolved to AllEntitiesModel["copypastas"]
.