Home > Software engineering >  Trouble inferring type with Typescript
Trouble inferring type with Typescript

Time:11-27

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.

Playground

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"].

  • Related