typescript - TypeScript:当提供变量 CLASS 作为函数参数时,将返回类型推断为该类的实例(仅来自参数)
问题描述
我想创建一个将实际类对象本身作为参数的函数(实际上是在一个充满多个参数的对象中),并且我希望将函数的返回类型推断为该类的实例,该类提供为论点。
这是一个 ORM,因此这些类是模型,每个模型都代表一个 SQL 表。然后会有许多数据库查询函数(完全在类之外),每个函数都接受参数来指示要从哪个表中选择等。
最好用代码解释...
export class DogModelClass {
id:number;
name:string;
woofCount:number;
}
export class CatModelClass {
id:number;
name:string;
meowCount:number;
}
interface ArgumentsInterface {
theActualClass; // <-- this argument will be the actual CLASS itself, NOT instance of the class
}
function getModelFromDatabase(args:ArgumentsInterface) {
// some database code to get the a "dog" or "cat" row from the DB and return an INSTANCE of the relevant args.theActualClass class
}
// I want typescript to infer that dogInstance is an INSTANCE of DogModelClass (simply from the function arguments alone)...
const dogInstance = getModelFromDatabase({theActualClass:DogModelClass});
// I want typescript to infer that catInstance is an INSTANCE of CatModelClass (simply from the function arguments alone)...
const catInstance = getModelFromDatabase({theActualClass:CatModelClass});
我知道我可以为函数本身添加一个泛型,即
function getModelFromDatabaseWithGeneric<ModelGeneric>(args:ArgumentsInterface):ModelGeneric {
return <ModelGeneric>{};
}
const dogInstance2 = getModelFromDatabaseWithGeneric<DogModelClass>({theActualClass:DogModelClass});
但我不想在每次调用函数时都设置泛型类型,因为模型类本身已经需要在参数中设置,因为其他原因(例如函数知道要从哪个表中选择等) )。因此,每次调用所有查询函数时都必须编写两次类名,这有点多余。
我怎样才能做到这一点?
如果有更准确的术语可以用于所有这些,请告诉我。在将它们作为像这样的变量传递时,我永远不太确定在 JS 中如何调用“实际的类对象 - 而不是实例”。
解决方案
实现这一点的一种方法是将泛型类型限制为类构造函数,然后返回其InstanceType
:
function getModelFromDatabase<T extends { new(...args: any[]): any }>(args: { theActualClass: T }): InstanceType<T> { /* ... */ }
或者,如果您愿意,通过确保参数始终是构造函数类型:
function getModelFromDatabase<T>(args: { theActualClass: {new (...args: any[]): T} }): T { /* ... */ }
两者都实现了相同的目标:
// Infered as an INSTANCE of DogModelClass
const dogInstance = getModelFromDatabase({theActualClass: DogModelClass});
// Infered as an INSTANCE of CatModelClass
const catInstance = getModelFromDatabase({theActualClass: CatModelClass});
推荐阅读
- python - 使用 plist 执行脚本时 macOS “env: python3: No such file or directory”
- svelte - 仅在客户端运行某些代码的最佳方法是什么?
- javascript - 未捕获的 TypeError:document.getElementById(...).addEventHandler 不是函数
- java - 从字符串中检索具体数据
- apache - 重定向到 https://www 与 RewriteBase 一起使用时如何修复未找到错误?
- embedded - 是否可以在闪存驱动器(笔式驱动器)上编写程序来执行将闪存驱动器插入 USB 端口的任务?
- javascript - 如何使用 go buffalo 框架渲染 quill js 内容
- python - 使用 ccrs.epsg() 绘制带有 EPSG 4326 坐标系的邮政编码周长 shapefile
- mql4 - 将 .tpl 文件类型合并到 TradingView 对图表中
- c# - 在运行时在 blazor 托管中编辑 .razor 文件