Dynamic table names Prisma Typescript error

Viewed 34

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.

1 Answers

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]
Related