You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否基于泛型参数将TypeScript泛型类型映射为另一类型?

TypeScript关联泛型类型的参数复用方案问题

我有一组包含多种相关泛型类型(及关联泛型约束)的API,下面是简化的示例,用常见类型模拟结构:

在使用这些类型时,我希望基于某个已有的具体类型创建相关的新类型,直接复用被引用类型的泛型参数,不用手动重复声明。目前我用的临时方案是在泛型接口里添加仅用于类型推导的假属性,但这种方式存在明显问题。

type Properties = { [name: string]: string }

interface SomeGeneric<A,B extends Properties,C extends HTMLElement> {
    someConcreteMethod: () => A
    someOtherConcreateMethod: (b: B) => void
    aConcreteProperty: C

    // 仅用于类型推导的假属性,运行时不存在,这种方式很糟糕,有没有更好的办法?
    relatedInterface?: RelatedInterface<A,B>
    anotherRelatedInterface?: AnotherRelatedInterface<A,C>
    thirdRelatedInterface?: ThirdRelatedInterface<A,B,C>
}

interface RelatedInterface<A,B extends Properties> {
    yetAnotherMethod: (a: A, b: B) => void
}

interface AnotherRelatedInterface<A,C extends HTMLElement> {
    oneMoreMethod: (c: C) => A
}

interface ThirdRelatedInterface<A,B extends Properties,C extends HTMLElement> {
    thirdMethod: (a: A, b: B, c: C) => () => void

    // 同样是假属性
    relatedInterface?: RelatedInterface<A,B>
    anotherRelatedInterface?: AnotherRelatedInterface<A,C>
}

type ConcreteB = { name: string };

interface SomeConcreteType extends SomeGeneric<string,ConcreteB,HTMLDivElement> {}

// 这些类型都属于同一关联体系,但并非只有一个"主类型",它们各自都有独立使用场景
// 如果把所有类型都基于SomeGeneric来定义,会导致创建独立类型时不得不声明无用的参数,所以不可行

// 手动重复泛型参数的写法,太繁琐
interface SomeConcreteRelatedInterfaceVerbosely extends RelatedInterface<string,ConcreteB> {}
interface AnotherConcreteRelatedInterfaceVerbosely extends AnotherRelatedInterface<string,HTMLDivElement> {}
interface ThirdConcreteRelatedInterfaceVerbosely extends ThirdRelatedInterface<string,ConcreteB,HTMLDivElement> {}

// 目前找到的唯一不用重复参数的方式:通过假属性推导类型
// 但所有关联类型都要加这类假属性,很不合理
type SomeConcreteRelatedInterfaceDeclaratively = SomeConcreteType["relatedInterface"]
type AnotherConcreteRelatedTypeDeclaratively = SomeConcreteType["anotherRelatedInterface"]
type ThirdConcreteTypeDeclaratively = SomeConcreteType["thirdRelatedInterface"]

type DerivedFromThirdTypeDeclaratively = ThirdConcreteTypeDeclaratively["anotherRelatedInterface"]

当前方案的核心问题

编译器会认为这些假属性是对象的真实属性,但实际上它们完全是为了类型推导凭空添加的,这会造成类型定义的误导。

已排查的思路

  • 映射类型不适用,它的作用是遍历类型键,和我的需求无关
  • 了解到可以用infer提取泛型参数(比如从数组类型中提取元素类型的示例),但不清楚如何将其应用到我的场景中,实现从已有类型提取泛型参数并转换为相关类型的效果:
export type ArrayElement<ArrayType extends readonly unknown[]> =
    ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
  • 查找过一些泛型约束相关的问题,但大多局限于单个类型内部的约束,没有找到跨类型泛型参数复用的方案。

内容的提问来源于stack exchange,提问作者David P. Caldwell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:35:38