Home > OS >  using keyof to get members and static members of class
using keyof to get members and static members of class

Time:09-04

I'm trying to define a type that will allow me to "tag" members and static members of some type.

Assuming I have the following class

class testCase{
a='';
static b='';
}

I want my function to receive the class as the first parameter (I need it) and a second parameter of options that are optional (event the static is optional) as follows:

myFunc(testCase, {a:true,static:{b:true});
or
myFunc(testCase, {static:{b:true});
or 
myFunc(testCase, {a:true);

I've played around with keyof, and couldn't get this to work. I can get keyof to work on the class or it's static - but not both:

I've tried:

export declare type Members<T, Y> = {
  [Properties in keyof Partial<T>]: boolean
} & {
  static?: {
    [Properties in keyof Partial<Y>]: boolean
  }
}

function myMembersFunction<T, Y extends { new(): T }>(c: Y, member: Members<T, Y>) {

}

But it doesn't work - and I'm not sure why

I've tried as a step on the way, creating the following function:

const members: keyof testCase = 'a';
const staticMembers: keyof typeof testCase = 'b';

function myFunction<T, Y extends { new(): T }>(c: Y, member: keyof T, staticMembers: keyof Y) {
  console.log({ member, staticMembers });
}
myFunction(testCase, "a", "b");

But got an interesting case that I don't understand, saying that when the third parameter is wrong, it marks it as wrong - that's great , but if the second parameter is wrong, it marks the first parameter as wrong

CodePudding user response:

Here is the solution (you can see it in action here):

type Members<T> = T extends new(...args: any[]) => infer R ? { [K in keyof R]?: boolean } : never;
type StaticMembers<T> = { [K in keyof T]?: boolean };

function myFunc<T>(ctor: T, options: Members<T> & { static?: StaticMembers<T> }): void {
  console.log(ctor, options);
}

Your basic idea was correct, it's just a little refinements. Most obvious is you don't need two arguments T and Y because they are basically the 1-to-1 thing which can be calculated from either of them.

  • Related