Home > Enterprise >  Defining setter in factory function using square bracket property access gives TypeScript error
Defining setter in factory function using square bracket property access gives TypeScript error

Time:08-17

I am trying to create a factory function that returns an object with a setter and getter. The object represents a predefined pseudo cache that can save data to a property. Here is my example:

interface CacheData {
  accessToken: string;
  expiration: number;
}

function cacheFactory(data: CacheData) {
  const cache: CacheData = data;
  return {
    getItem(key: string) {
      return cache[key as keyof CacheData];
    },
    setItem(key: string, value: unknown) {
      cache[key as keyof CacheData] = value; // HERE I GET THE ERROR!
    },
  };
}

Playground

I receive the error Type 'unknown' is not assignable to type 'never'. at cache[key as keyof CacheData] = value;

How can I solve this error?

CodePudding user response:

You shouldn't be using type assertions here at all. For type safety you want to already know whether key is a valid key of CacheData, then you can use which key to determine the appropriate parameter/return type:

function cacheFactory(data: CacheData) {
  const cache: CacheData = data;
  return {
    getItem<K extends keyof CacheData>(key: K): CacheData[K] {
      return cache[key];
    },
    setItem<K extends keyof CacheData>(key: K, value: CacheData[K]): void {
      cache[key] = value;
    },
  };
}

Playground


As pointed out in the comments you could also make the type of data/cache generic, so your cacheFactory is more reusable:

function cacheFactory<T>(data: T) {
  const cache: T = data;
  return {
    getItem<K extends keyof T>(key: K): T[K] {
      return cache[key];
    },
    setItem<K extends keyof T>(key: K, value: T[K]): void {
      cache[key] = value;
    },
  };
}

Playground

CodePudding user response:

As a workaround you can do:

cache[key as keyof CacheData] = (value as never);

This will get rid of the error message.

  • Related