Home > Software engineering >  Getting typing for function parameters from deep nested type
Getting typing for function parameters from deep nested type

Time:03-14

I am trying to solve an issue getting deep nested parameters.

If I am getting parameters from non nested type, everything is working fine

export type test = {
  'fnc1': () => void,
  'fnc2': () => void,
  'fnc3': () => void,
  'fnc4': () => void,
}
export type FncParams<key extends keyof test> = Parameters<test[key]>;

But when I am trying to do it deeply, I am getting typescript error. Note that typing is working (I mean code hinting) except error during compilation.

export type testDeep = {
  'key1': {
    'fnc1': () => void,
    'fnc2': () => void,
  },
  'key2': {
    'fnc3': () => void,
    'fnc4': () => void,
  }
}
export type FncDeepParams<
  key extends keyof testDeep,
  event extends keyof testDeep[key]
> = Parameters<testDeep[key][event]>;
Type 'testDeep[key][event]' does not satisfy the constraint '(...args: any) => any'.
  Type 'testDeep[key][keyof testDeep[key]]' is not assignable to type '(...args: any) => any'.

What helped is to add [x:string]: (...args: any) => void into testDeep, but then I lose all typing helps

Is there way to satisfy constraint without doing it too generic?

Thanks!

CodePudding user response:

Is there way to satisfy constraint without doing it too generic?

I'm not exactly sure what that means, but here's a solution that will allow you to index function parameters on nested objects like in your example:

TS Playground

type Fn<Params extends readonly any[] = readonly any[], Result = any> =
  (...params: Params) => Result;

type FnInObject<O extends Record<K, Fn>, K extends PropertyKey> = O[K];

type NestedFunctions = {
  key1: {
    fnc1: (param: string) => void;
    fnc2: (param: number) => void;
  };
  key2: {
    fnc3: (param: boolean) => void;
    fnc4: (param: null) => void;
  };
};

type NestedFnParams<
  O extends Record<PropertyKey, Record<PropertyKey, Fn>>,
  K0 extends keyof O,
  K1 extends keyof O[K],
> = Parameters<O[K0][K1]>;

type P1 = NestedFnParams<NestedFunctions, 'key1', 'fnc1'>; // [param: string]
type P2 = NestedFnParams<NestedFunctions, 'key1', 'fnc2'>; // [param: number]

type P3Invalid = NestedFnParams<NestedFunctions, 'key1', 'fnc3'>; // never

type P3 = NestedFnParams<NestedFunctions, 'key2', 'fnc3'>; // [param: boolean]
type P4 = NestedFnParams<NestedFunctions, 'key2', 'fnc4'>; // [param: null]

  • Related