【问题标题】:Fetch type of property from a generic type从泛型类型中获取属性类型
【发布时间】:2020-01-29 02:03:14
【问题描述】:

我正在写一些东西,我需要获取给定类型的属性类型:

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 值。

【问题讨论】:

  • 例如,FooBarType['foo'] 已经返回 string
  • @ChristianIvicevic 我如何以编程方式访问它?
  • 由于 Typescript 类型在编译期间被擦除,如果您感兴趣的类型不是一般的 JS 类型,则通常在运行时无法获取此信息(除非您使用带有更多元数据的反射)。我想知道为什么您首先要在运行时查询类型?通常这不是必需的。
  • @ChristianIvicevic 我正在构建一个基于环境变量的对象,其中所有内容显然都以字符串形式出现,具有键入内容的能力自然会使事情变得更容易。我有一个默认配置,它可能有一些未定义的东西,并留给环境稍后添加配置,但我想避免有一个列出进程和默认以及其他输入设备的大型配置文件。
  • 您能否提供一个 MWE,说明您希望将此 getType 方法具体用于什么用途?具体展示你想如何使用这个方法的返回值,因为我认为你想做一些不合理的事情。

标签: typescript typescript-generics


【解决方案1】:

正如评论中所说,您已经可以使用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

【讨论】:

  • 我不认为OP想要访问实际值但想要字符串化类型,所以getValue(obj, 'foo') === 'string'等,基本上是运行时的元编程/反射。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 2015-02-15
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
  • 2018-02-16
相关资源
最近更新 更多