[SOLVED] Dynamic table names Prisma Typescript error

Issue

This Content is from Stack Overflow. Question asked by Michael Soriano

Struggling with Typescript lint errors when using dynamic table names and Prisma. I have the following code:

type Mode =  'category' | 'ingredients';
let mode: Mode;    
mode = req.query.mode as Mode;


if(mode === 'category'){
    const table = 'category';
    const lookup = 'categoriesOnDishes';
    const lookupItemIdKey = 'categoryId';
}else if(mode === 'ingredients'){
    const table = 'ingredient';
    const lookup = 'ingredientsOnDishes';
    const lookupItemIdKey = 'ingredientId';
}

let lookupData = await prisma?.[lookup].findMany({
                where : {
                        dishId : did
                    } 
    })

the error is:

enter image description here

Element implicitly has an ‘any’ type because expression of type ‘any’ can’t be used to index type ‘PrismaClient<PrismaClientOptions, never, RejectOnNotFound | RejectPerOperation | undefined>’

How to fix this issue.

Thanks in advance.



Solution

If you hover over lookup, it will show an extra error Cannot find name 'lookup'. The reason is that table, lookup and lookupItemIdKey are block-scoped constants, which are not visible in the outside scope.

You could declare three separate conditional constants (const table = mode === 'category' ? 'table' : 'ingredient', etc.), but you can also use destructuring to declare all three in one go:

const {table, lookup, lookupItemIdKey} = mode === 'category' ? {
  table: 'category',
  lookup: 'categoriesOnDishes',
  lookupItemIdKey: 'categoryId',
} : {
  table: 'ingredient',
  lookup: 'ingredientsOnDishes',
  lookupItemIdKey: 'ingredientId',
}

If there are more than two modes, and you don’t want to have nested conditional expressions, you could also use an object:

const modeConstants: Record<Mode, Record<'table' | 'lookup' | 'lookupItemIdKey', string>> = {
  category: {
    table: 'category',
    lookup: 'categoriesOnDishes',
    lookupItemIdKey: 'categoryId',
  }, 
  ingredients: {
    table: 'ingredient',
    lookup: 'ingredientsOnDishes',
    lookupItemIdKey: 'ingredientId',
  }
}

const {table, lookup, lookupItemIdKey} = modeConstants[mode]


This Question was asked in StackOverflow by Michael Soriano and Answered by Oblosys It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?