Выбрать тип свойства из универсального типа - PullRequest
0 голосов
/ 29 сентября 2019

Я пишу что-то, в чем мне нужно получить тип свойства для данного типа:

type FooBarType {
    foo: string,
    bar: number
}

Функция будет выглядеть так: getType<K extends keyof T>(key: K): string, и такой результат вызовафункция с foo в качестве параметра будет string:

getType<FooBarType>('foo' as as keyof FooBarType) // string

У меня нет реализации универсального в этой точке, поэтому использование индексированных типов доступа кажется не так?

Возможно ли это?

Пока у меня есть это:

getType <K extends keyof T>(key: K): string {
    type property = T[keyof T]
    // not sure how to continue here as I can't use T as a value
}

MWE:

type Config {
    database_host: string,
    database_pass: string | undefined,
}

const defaultConfig: Config = {
    database_host: 'host',
    database_pass: undefined
}

const config = ConfigBuilder<Config>.resolve(defaultConfig, new EnvironmentVars(), new YamlFiles(['../path/to/yaml']))

class ConfigBuilder<T> {

   public resolve(...): T {
     // from default: key: string
     const configKey: keyof ConfigType = key as keyof ConfigType
     if (foundValues.hasOwnProperty(key.toUpperCase())) {
            config[configKey] = this.parse(configKey, foundValues[key]) 
     }
   }

   private parse<K extends keyof ConfigType>(key: K, value: any): ConfigType[K] {
        const type = this.getConfigKeyType(key)

        if (this.parserDictionary[type]) {
            return this.parserDictionary[type].parse(value)
        }

        throw Error(`Could not find parser for type ${type}`)
    }

    private getConfigKeyType<K extends keyof ConfigType>(key: K): string {
        type configItems = ConfigType[keyof ConfigType]

    }

}

// config {
//     database_host: 'host',
//     database_pass: 'pass'    
// }

Либо, либо нет от env. vars или проанализированные файлы могут предоставить значение database_pass.

1 Ответ

0 голосов
/ 29 сентября 2019

Как сказано в комментарии, вы уже можете сделать это с FooBarType['foo'].

Если вы хотите это программно, набрав:

interface FooBarType {
    foo: string;
    bar: number;
}

const obj: FooBarType = {
   foo: '',
   bar: 1
}

function getValue<T, K extends keyof T>(obj: T, key: K): T[K] {
   return obj[key];
}

getValue(obj, 'foo'); // return string value
getValue(obj, 'bar'); // return number value
...