在 TypeScript 中使泛型参数的顺序变得多余?
Posted
技术标签:
【中文标题】在 TypeScript 中使泛型参数的顺序变得多余?【英文标题】:Make the order of generic arguments redundant in TypeScript? 【发布时间】:2022-01-03 12:16:49 【问题描述】:我有一个中间件引擎,它使用与特定实现相关的各种通用参数键入。
export type Middleware<
Store = never,
Args = unknown,
Response = unknown
> = (
context:
endpoint: string
args: Args
locals:
store?: Store,
[key: string]: unknown
) => Promise<Response|void>|Response|void
随着我使Middleware
的功能更加丰富,通用参数列表不断增加。有时 store
不会出现,而其他参数则存在。我知道我可以依赖默认值和参数顺序,但是(有更多参数在路上)这不是最好的开发人员体验,必须以正确的顺序列出参数并提供 unknown
或 never
给即将到来的参数在其他需要定义之前。
有没有更好的方法为不依赖顺序的泛型提供参数,这样我可能有任意数量的相关泛型参数,其余的默认为最一般情况下定义的东西?也许是某种地图?
【问题讨论】:
不。 javascript 没有命名参数! @jonrsharpe 您可以通过使用对象在 JavaScript 中有效地命名参数。所以你可以达到同样的目的。 TypeScript 中没有类似的 hack 吗?或者任何其他技巧来减少在泛型中传递冗余参数的需要? 有效但不是,你知道,实际上。 我不确定拥有一个使用许多类型参数的 generic 是否是个好主意,其中一些参数可能相关,也可能不相关。在这种情况下听起来不是很“通用”。 也许你可以做一些事情,比如接受一个泛型类型参数,这是context
结构的一个选项,但是,也许最好重新考虑这种方法。
有时过于通用的函数不是一个好主意
【参考方案1】:
您可以使用带有属性的单一类型:
type Get<T, K extends PropertyKey, TDefault> =
[T] extends [Record<K, infer U>] ? U: TDefault
export type Middleware<T extends
Store?: any,
Args?: any,
Response?: any
> = MiddlewareInternal<Get<T, 'Store', never>, Get<T, 'Args', unknown>, Get<T, 'Response', unknown>>
export type MiddlewareInternal<
Store = never,
Args = unknown,
Response = unknown
> = (
context:
endpoint: string
args: Args
locals:
store: Store,
[key: string]: unknown
) => Promise<Response|void>|Response|void
Playground Link
它可能不是 100% 等效的,但它可能已经足够了。
【讨论】:
谢谢你;已经投票了,因为它在某种程度上允许我隐藏实现的复杂性。但我认为它的复杂性暗示了 cmets 中关于我的原始设计缺乏通用性的观点。我现在正在重新考虑如何构建我的泛型。 @shennan 我倾向于同意拥有大量通用参数是一个不好的迹象,所以你可能会考虑改变你的设计。以上是关于在 TypeScript 中使泛型参数的顺序变得多余?的主要内容,如果未能解决你的问题,请参考以下文章