javascripttypescriptkeyof

How to refer to static field in mapped types in TypeScript?


I can get a type representing class members like this:

    class ClassWithFields {
        public instanceMember: {a: string, b: number};
        public secondInstanceMember: {q: "q"};
        public static staticMember: {c: string, d: Date};
    }
    type getClassFieldType<TClass, TKey extends keyof TClass> = TClass[TKey];
    type getClassFieldFields<TClass, TKey extends keyof TClass> = keyof TClass[TKey];
    
    /**
     * Resolves to:
     *      const testClassFieldType: {
     *           q: "q";
     *      }
     * IDE suggests following things for second template arg: instanceMember, secondInstanceMember
     */
    const testClassFieldType: getClassFieldType<ClassWithFields, "secondInstanceMember">;

    /**
     * Resolves to:
     *     const testGetClassFieldFields: "a" | "b"
     */
    const testGetClassFieldFields: getClassFieldFields<ClassWithFields, "instanceMember">;

I want the same, specifically the list of fields, in a static field. That is I want a type that given ClassWithFields and "staticMember", should resolve to key list containing "c"|"d".


Solution

  • To refer to a class itself (not its instance), use typeof:

    Playground

        class ClassWithFields {
            declare public instanceMember: {a: string, b: number};
            declare public secondInstanceMember: {q: "q"};
            public static staticMember: {c: string, d: Date};
        }
        type getClassFieldType<TClass, TKey extends keyof TClass> = TClass[TKey];
        type getClassFieldFields<TClass, TKey extends keyof TClass> = keyof TClass[TKey];
        
        
        declare const testGetClassFieldFields: getClassFieldFields<typeof ClassWithFields, "staticMember">;