简体   繁体   中英

Typescript generics and keyof

I have issues with keyof and generics. Have two objects: one argument Config , second result MyFilter . MyFilter should be created with keys of Config . Please help:

enum Type {
  Boolean,
  Number,
  String,
}

// f.e. { name: Type.String, age: Type.Number }
interface Config {
  [key: string]: Type;
}

// should have the same keys as Config and corresponding types, f.e. { name: "Expecto Patronum!", age: 43 }
type MyFilter<C extends Config> = {
  [Key in keyof C]: C[Key] extends Type.Boolean
    ? boolean
    : C[Key] extends Type.Number
    ? number | null
    : C[Key] extends Type.String
    ? string | null
    : undefined;
};

// C and F should have same keys, but how to create F var and iterate over C to fill F with keyof
function createFilter<C extends Config = Config, F extends MyFilter<C> = MyFilter<C>>(config: C): F {
    const filter = {}

    // DO loop
    switch (config[key]) {
        case Type.Boolean:
            filter[key] = true
        case Type.Number:
            filter[key] = 43
        case Type.String:
            filter[key] = "Expecto Patronum!"
    }
    // END loop

    return filter
}

Playground Example

It is not necessary for filter to be a generic. Then using the for...in you can iterate over the object. Then utilize type casting with the as operator to assert the type.

function createFilter<C extends Config = Config>(config: C): MyFilter<C> {
    const filter: Record<string, any> = {}

    // DO loop
    for (const key in config) {
      switch (config[key]) {
        case Type.Boolean:
            filter[key] = true
        case Type.Number:
            filter[key] = 43
        case Type.String:
            filter[key] = "Expecto Patronum!"
    }
    }
    // END loop

    return filter as MyFilter<C>
}

TS Playground Link

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM