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

TypeScript泛型构造函数字典类型不匹配问题及解决方案咨询

解决类型不匹配与禁用any的泛型方案

核心问题分析

  • 原字典ObjStorerDictionary强制所有构造函数接受StoredObj类型,但FooMaker/BarMaker实际要求更具体的Foo/Bar类型,导致类型不兼容。
  • constructObjectStorerFromJson需要通过泛型关联下拉选项名称与对应参数/返回类型,彻底规避any。

具体修复步骤

1. 定义存储对象的类型映射

创建映射类型,将下拉选项名称与对应的具体存储对象类型绑定:

type StoredObjMap = {
  "Foo": Foo;
  "Bar": Bar;
};

2. 修正字典的类型定义

基于StoredObjMap重构字典类型,确保每个键对应的构造函数类型精准匹配:

const ObjStorerDictionary: {
  [K in keyof StoredObjMap]: ObjStorerConstructor<StoredObjMap[K]>
} = {
  "Foo": FooMaker,
  "Bar": BarMaker,
};

此时TypeScript会自动校验每个构造函数的参数类型,原类型不匹配错误将消失。

3. 改造构造函数,移除any

用泛型K约束输入名称为StoredObjMap的键,自动推导参数与返回类型:

const constructObjectStorerFromJson = <K extends keyof StoredObjMap>(
  name: K,
  args: StoredObjMap[K]
): ObjStorer<StoredObjMap[K]> => {
  const Constructor = ObjStorerDictionary[name];
  return new Constructor(args);
};

现在函数会根据传入的name自动校验args合法性,返回对应类型的ObjStorer实例,完全无需any。

完整代码示例

interface StoredObj {
    name: string;
    [key: string]: unknown;
};

interface ObjStorer<SpecificStoredObj extends StoredObj> {
    makeStoredObj: () => SpecificStoredObj
}

export interface ObjStorerConstructor<SpecificStoredObj extends StoredObj> {
    new(storedObj: SpecificStoredObj): ObjStorer<SpecificStoredObj>
}

/////////////// FooMaker ////////////////
interface Foo extends StoredObj {
    name: "Foo",
    fooProperty: string
}

class FooMaker implements ObjStorer<Foo>{
    constructor(storedObj: Foo) {
        // do stuff
    }
    makeStoredObj(): Foo {
        return { name: "Foo", fooProperty: "fooo" }
    }
}

/////////////// BarMaker ///////////////
interface Bar extends StoredObj {
    name: "Bar",
    barProperty: string
}

class BarMaker implements ObjStorer<Bar>{
    constructor(storedObj: Bar) {
        // do stuff
    }
    makeStoredObj(): Bar {
        return { name: "Bar", barProperty: "baaar" }
    }
}

////////////// 类型映射与修正字典 ///////////////
type StoredObjMap = {
  "Foo": Foo;
  "Bar": Bar;
};

const ObjStorerDictionary: {
  [K in keyof StoredObjMap]: ObjStorerConstructor<StoredObjMap[K]>
} = {
  "Foo": FooMaker,
  "Bar": BarMaker,
};

////////////// 改造后的构造函数 ///////////////
const constructObjectStorerFromJson = <K extends keyof StoredObjMap>(
  name: K,
  args: StoredObjMap[K]
): ObjStorer<StoredObjMap[K]> => {
  const Constructor = ObjStorerDictionary[name];
  return new Constructor(args);
};

// 合法调用示例
const fooStorer = constructObjectStorerFromJson("Foo", { name: "Foo", fooProperty: "test" });
const barStorer = constructObjectStorerFromJson("Bar", { name: "Bar", barProperty: "test" });
// 非法调用会被TypeScript捕获:参数类型不匹配
// const wrongStorer = constructObjectStorerFromJson("Foo", { name: "Foo", barProperty: "test" });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 07:03:15