从对象动态创建类型

从对象动态创建类型

本文介绍了从对象动态创建类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有以下两种类型:

export type CollectionNames = 'twitter:tweets' | 'twitter:users' | 'twitter:metadata-cashtag'

export type CollectionType<T extends CollectionNames> =
    T extends 'twitter:tweets' ? Tweet :
    T extends 'twitter:users' ? User :
    T extends 'twitter:metadata-cashtag' ? CashtagMetadataDb :
    never

我觉得这很笨拙,而且我不太热衷于两次演奏琴弦.同样,在后一种类型中可能会误将它们拼写错误.

I feel this is very clunky and I'm not very keen on having the strings twice. Also it's possible to legally misspell them in the latter type.

有什么方法可以从这样的对象动态创建它们:

Is there any way to create these dynamically from an object such as this:

typings = {
    'twitter:tweets': Tweet,
    'twitter:users': User,
    'twitters:metadata-cashtag': CashtagMetadataDb
}

这个想法是,多个模块将具有自己的CollectionType类型,然后在导入的根模块中聚合为一个CollectionType类型.因此,如果我有两个使用* as导入的模块CoinTwitter,它看起来像这样:

The idea is that multiple modules will have their own CollectionType type which is then aggregated into one CollectionType in the importing root module. So if I have two modules Coin and Twitter imported using * as, it looks something like this:

type CollectionName = Twitter.CollectionNames | Coin.CollectionNames

type CollectionType<T extends CollectionName> =
    T extends Twitter.CollectionNames ? Twitter.CollectionType<T> :
    T extends Coin.CollectionNames ? Coin.CollectionType<T> :
    never

这些将在类似的函数中使用,其中类型是后一种类型(Collection来自MongoDB):

These will then be used in a function like so where the types are of the latter kind (Collection here is from MongoDB):

async function getCollection<T extends CollectionName> (name: T): Promise<Collection<CollectionType<T>>>

推荐答案

我认为在这种情况下,您根本不需要条件类型.您可以使用 keyof和查找类型.您可能可以创建一个像typings这样的对象并从中派生类型,但是除非您在运行时需要该对象用于某些东西(并且必须放置类型为TweetUser等的对象)左右)我想说的是,您应该只创建这样的接口类型:

I think in this case you don't need conditional types at all; you can do this with keyof and lookup types instead. You probably could create an object like typings and derive a type from it, but unless you need that object for something at runtime (and have objects of type Tweet, User, etc lying around) I'd say you should just make an interface type like this:

export interface Collections {
  'twitter:tweets': Tweet,
  'twitter:users': User,
  'twitter:metadata-cashtag': CashtagMetadataDb
}

然后,可以根据该类型定义您的CollectionNamesCollectionType类型:

Then, your CollectionNames and CollectionType types can be defined in terms of that type:

export type CollectionNames = keyof Collections;
export type CollectionType<K extends CollectionNames> = Collections[K];

您可以验证上述类型是否与您的定义相同.如果您有多个导出了Collections类型的模块,则可以简单地使用接口扩展合并它们,并从中导出CollectionNamesCollectionType:

You can verify that the above types act the same as your definitions. In the case that you have multiple modules that have exported Collections types, you can simply merge them using interface extension and re-derive CollectionNames and CollectionType from it:

export interface Collections extends Twitter.Collections, Coin.Collections {}
export type CollectionNames = keyof Collections;
export type CollectionType<K extends CollectionNames> = Collections[K];

希望有帮助.祝你好运!

Hope that helps. Good luck!

这篇关于从对象动态创建类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 00:09