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

TypeScript:如何根据传入的子类类型推导对应选项类型

问题

给定第三方不可修改的类结构:

class Parent {}
class Child1 extends Parent {}
class Child2 extends Parent {}

需要实现函数doSomething,接收子类实例和对应选项,不同子类要求不同的选项结构,需实现选项的自动补全与类型校验。

最初尝试用索引接口定义选项类型,但无法将类作为索引类型:

interface SomeOptions {
    Child1: {foo: string},
    Child2: {id: number},
}

改为数组形式的类型定义:

type SomeOptions = [
    {class: Child1, options: {foo: string}},
    {class: Child2, options: {id: number}},
]

现在需要实现类型FindMeTheCorrectOption<T>,让函数:

const doSomething = <T extends Parent>(someClass: T, options: FindMeTheCorrectOption<T>) => {}

能根据传入的子类实例自动匹配对应选项类型,达到以下效果:

doSomething(new Child1(), {foo: 'bar'}); // 类型合法
doSomething(new Child2(), {id: 1}); // 类型合法
doSomething(new Child2(), {foo: 1}); // TypeScript报错,foo应为string类型

请问如何实现该类型推导?

解决方案

1. 修正选项映射的类型定义

首先需要把数组形式的SomeOptions中class字段的类型改为构造函数类型(typeof Child1而非实例类型Child1),这样才能通过实例的构造函数关联选项:

type SomeOptions = [
    {class: typeof Child1, options: {foo: string}},
    {class: typeof Child2, options: {id: number}},
];

基于这个数组,转换为以构造函数为键、选项类型为值的映射类型:

type ClassToOptions = {
  [Item in SomeOptions[number] as Item['class']]: Item['options']
};

2. 实现FindMeTheCorrectOption<T>

通过实例类型T获取其构造函数类型,再到ClassToOptions中查找对应选项:

type FindMeTheCorrectOption<T extends Parent> = ClassToOptions[typeof T];

3. 最终函数实现

将类型代入函数定义即可:

const doSomething = <T extends Parent>(someInstance: T, options: FindMeTheCorrectOption<T>) => {};

验证效果

此时代码会按预期工作:

  • doSomething(new Child1(), {foo: 'bar'}):类型校验通过
  • doSomething(new Child2(), {id: 1}):类型校验通过
  • doSomething(new Child2(), {foo: 1}):TypeScript抛出错误,提示选项结构不匹配

扩展说明

后续新增子类时,只需在SomeOptions数组中添加对应的{class: typeof 子类, options: 对应选项类型}条目,映射类型和推导逻辑会自动适配新的子类,无需修改其他代码。

内容的提问来源于stack exchange,提问作者Robin Schambach

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 09:40:26