Home > Back-end >  Getting the type for an key to define function argument
Getting the type for an key to define function argument

Time:12-22

I have an type like the follow example

export type Signals = {
    activity: boolean;
    quest: string;
    creator: number;
}

With this type i would get an function that has followed properties

export function initStation<T>(){
    return {
        signal: (id: keyof T, value: T[keyof T]){
            // code
        }
    }
}

But when i use this implemetation i have all the time an union type vor the value argument. Even when the id argument is setted as activity, quest or creator.

I try to get a better support, when the id is for example equal activity then the possible type is just a boolean, cause in my type above is activity defined as boolean.

I expected to call my function like

const station = initStation<Signals>()

station.signal('activity', true); // fine
station.signal('quest', 'any quest'); // fine
station.signal('creator', 1234); // fine

and getting error when i try to use the function like below

station.signal('activity', 'abc'); // error
station.signal('quest', 123); // error
station.signal('creator', true); // error

CodePudding user response:

If id is of type keyof T and value is of type T[keyof T], then they will both be uncorrelated union types and nothing will stop someone from passing in an id and a value corresponding to different properties from T. One way to fix this is to make your method generic in the type of id, K extends keyof T, and then have value represented in terms of that:

export function initStation<T>() {
  return {
    signal: <K extends keyof T>(id: K, value: T[K]){
      // code
    }
  }
}

This gives you the behavior you desire:

const station = initStation<Signals>();

station.signal('activity', true); // fine
station.signal('quest', 'any quest'); // fine
station.signal('creator', 1234); // fine
station.signal('activity', 'abc'); // error
station.signal('quest', 123); // error
station.signal('creator', true); // error

Playground link to code

  • Related