Mabeh Al-Zuq Yadeek
Mabeh Al-Zuq Yadeek

Reputation: 84

How to fix "Argument of type 'string' is not assignable to parameter of type 'never'" with use of keyof type definition

I'm using a central Redux store and have the following action typed:

setProperty: <AppState, K extends keyof AppState>(
      key: K,
      value: AppState[K]
    ): void => {
      set({
        [key]: value,
      });
    }

AppState is the following:

type AppState = {
loading: boolean;
error: string;
data: DataDTO;
};

So the action takes a key (which has to be a key that is defined in the AppState type), and takes a value parameter, which is one of the type definition of the individual keys of AppState. So key can only be loading, error and data, while the value parameter can only be of type boolean, string or DataDTO.

However, when I use the setProperty action:

  setProperty(
    'data',
    computedData
  );

Typescript fires an error for the "data" string, saying that:

Argument of type 'string' is not assignable to parameter of type 'never'

It's saying that no type is expected and I gave it a string, so it's throwing an error. How can I go about fixing this and getting it to work nicely with typescript?

Thanks for any help!

Upvotes: 2

Views: 12486

Answers (1)

tenshi
tenshi

Reputation: 26324

The problem is right here:

    setProperty: <AppState, K extends keyof AppState>(
      key: K,
      value: AppState[K]
    ): void => {
      set({
        [key]: value,
      });
    }

The first generic parameter AppState shadows the existing type AppState. Because TypeScript cannot infer what this generic parameter is when you call it, keyof AppState is never.

So to solve it, just remove it entirely:

    setProperty: <K extends keyof AppState>(
      key: K,
      value: AppState[K]
    ): void => {
      set({
        [key]: value,
      });
    }

Playground

Upvotes: 1

Related Questions