Home > Software design >  Newbie in TypesSript - How to check an interface by an index
Newbie in TypesSript - How to check an interface by an index

Time:02-19

I have a list of operations to a DB and every one of them have a different set of variables which need to be passed on, I figured it would be much easier to add new operations if I set the interfaces inside a list, like this, where if there is a match the function would require the correct interface for that operation:

const operation = {
    add: 'example',
    list: 'example2',
};
interface operationVariable {
    add: { asset: string };
}

I'm trying to get the correct interface for each operation from a list like this:

function graphql<OP = keyof typeof operation>(request: OP, variables: operationVariable[OP], server = CONFIG.GRAPHQLSERVER) {
    return post(server, request);
}

An error message comes up:

Type 'OP' cannot be used to index type 'operationVariable'.

Even if I remove the 'list' operation the error still persists...

How do I tell TypeScript to behave the way I want?

CodePudding user response:

Tell TypeScript that operation is a record that uses keys of operationVariable and holds strings:

const operation: Record<keyof operationVariable, string> = {
    add: 'example',
    list: 'example2', // error, not in operationVariable
};

Then the part you were missing is extends. The extends keyword is a generic constraint that you can use to tell TypeScript that this generic type must be a subtype of another type:

function graphql<
    OP extends keyof typeof operation
//     ^^^^^^^ OP is a keyof typeof operation
>(request: OP, variables: operationVariable[OP], // works

Here's how the handbook explains it.

  • Related