从对象动态创建输入

问题描述 投票:0回答:1

说我有以下两种类型:

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

我觉得这很笨重,而且我不太热衷于两次琴弦。也可以在后一种类型中合法地拼错它们。

有没有办法从这样的对象动态创建它们:

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

这个想法是多个模块将拥有自己的CollectionType类型,然后在导入根模块中聚合成一个CollectionType。所以,如果我使用Coin导入两个模块Twitter* as,它看起来像这样:

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):

async function getCollection<T extends CollectionName> (name: T): Promise<Collection<CollectionType<T>>>
typescript dynamic-typing conditional-types
1个回答
2
投票

我认为在这种情况下你根本不需要条件类型;你可以用keyof and lookup types来做这件事。您可能可以创建一个像typings这样的对象并从中派生出一个类型,但除非您在运行时需要该对象(并且有TweetUser等类型的对象),我会说你应该只创建一个接口类型像这样:

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

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

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

您可以验证上述类型的行为与您的定义相同。如果您有多个已导出Collections类型的模块,您可以使用接口扩展简单地合并它们,并从中重新导出CollectionNamesCollectionType

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

希望有所帮助。祝好运!

© www.soinside.com 2019 - 2024. All rights reserved.