Typescript doesn't narrow types in case of explicit object keys and string type

Advertisements

I have next setup:

export const PRISMA_TYPES_TO_TS = {
  'Int': 'number',
  'BigInt': 'number',
  'Decimal': 'number',
  'Float': 'number',
  'String': 'string',
  'Bytes': 'string',
  'Boolean': 'boolean',
  'DateTime': 'Date',
};


const randomKey: string = "randomKey"; // value can be different

if (PRISMA_TYPES_TO_TS.hasOwnProperty(randomKey)) {
  // here is TS error "No index signature with a parameter of type 'string' was found on type"
  console.log('type is good', PRISMA_TYPES_TO_TS[randomKey]);
} else {
  console.log('value is not good');
}

The problem is that typescript doesn’t narrow types after check with
PRISMA_TYPES_TO_TS.hasOwnProperty(randomKey)

What can be other ways of narrowing types for such case?

>Solution :

That’s due to the signature of hasOwnProperty:

hasOwnProperty(v: PropertyKey): boolean;

It has no predicate, it’s not a type guard so the compiler won’t narrow anything.

As it is not possible to write a generic type guard, you will need to use a type assertion :

if (PRISMA_TYPES_TO_TS.hasOwnProperty(randomKey)) {
  // here is TS error "No index signature with a parameter of type 'string' was found on type"
  console.log('type is good', PRISMA_TYPES_TO_TS[randomKey as keyof typeof PRISMA_TYPES_TO_TS]);
} else {
  console.log('value is not good');
}

Playground

Leave a ReplyCancel reply