如何将字符串或类传递给方法来创建实例

2023-12-08

我将使用以下方法,它通过向其传递类型来工作,例如obj.addComponent(MyClass)。这很好用。

我尝试修改type参数通过添加| string到它,但它现在给我错误说:

不能将“new”与类型缺少调用或构造签名的表达式一起使用。

无论如何,我是否可以修改它,以便我可以传递类名或类的字符串版本?

这是我所拥有的不起作用的:

public addComponent<T extends Component>(type: ComponentType<T> | string): T {
    let comp;
    comp = new type() as T;
    comp.name = comp.constructor.name;
}

这是它的依赖项:

class Component extends Obj {

}

interface ComponentType<T extends Component> {
    new(): T;
}

我尝试过使用Object.create(),工作正常,但随后我收到一个新错误:

未捕获的类型错误:无法分配给对象“[object Object]”的只读属性“名称”

Edit:

最后我希望能够将以下内容传递给addComponent:

obj.addComponent(MyClass);

Or

obj.addComponent("MyClass");

没有办法在javascript中使用名称来获取类,它没有类似于java的东西ClassLoader.
您可以通过创建自己的机制来解决这个问题,并且可能有很多方法可以做到这一点,但这里有 3 个选项。

(1) 维护组件类的注册表:

const REGISTRY: { [name: string]: ComponentType<Component> } = {};

class Component {}

class MyComponent1 extends Component {}
REGISTRY["MyComponent1"] = MyComponent1;

class MyComponent2 extends Component {}
REGISTRY["MyComponent2"] = MyComponent2;

type ComponentType<T extends Component> = {
    new(): T;
}

function factory<T extends Component>(type: ComponentType<T> | string): T {
    return typeof type === "string" ?
        new REGISTRY[type]() as T:
        new type();
}

(操场上的代码)

如果您采用这种方法,那么我建议REGISTRY一个保存集合的对象,这样您就可以只添加 ctor 并从中获取名称。

有一个变体,那就是使用装饰器:

function register(constructor: typeof Component) {
    REGISTRY[(constructor as any).name] = constructor;
}

@register
class MyComponent1 extends Component {}

@register
class MyComponent2 extends Component {}

(操场上的代码)

(2) 将组件包装在命名空间中(正如 @Shilly 在评论中建议的那样):

namespace components {
    export class Component {}
    export class MyComponent1 extends Component {}
    export class MyComponent2 extends Component {}

    export type ComponentType<T extends Component> = {
        new(): T;
    }

    export function forName(name: string): ComponentType<Component> {
        if (this[name] && this[name].prototype instanceof Component) {
            return this[name];
        }
    }
}

function factory<T extends components.Component>(type: components.ComponentType<T> | string): T {
    return typeof type === "string" ?
        new (components.forName(type))() as T:
        new type();
}

(操场上的代码)

如果您采用这种方法,那么您需要确保导出所有组件类。

(3)使用eval

class Component {}
class MyComponent1 extends Component {}
class MyComponent2 extends Component {}

type ComponentType<T extends Component> = {
    new(): T;
}

function factory<T extends Component>(type: ComponentType<T> | string): T {
    return typeof type === "string" ?
        new (eval(type))() as T:
        new type();
}

(操场上的代码)

这不是推荐的方法,您可以阅读所有关于缺点的信息在使用eval在很多地方。
但这仍然是一个选择,所以我将其列出。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将字符串或类传递给方法来创建实例 的相关文章

随机推荐

  • Android:扩展 SeekBar 时如何从 AccessibilityEvents 中消除语音文本?

    我的 Android 应用程序包含一个基于SeekBar 并且我想将自定义文本短语附加到我的控件以解释其对辅助功能的使用 我已经使用成功完成了此操作View setContentDescription text 当我请求将焦点集中在滑块控件
  • 使用控件名称作为字符串转换为控件[重复]

    这个问题在这里已经有答案了 我的 XIB 中有几个文本字段 和标签 在我的应用程序中的某个时刻 我动态构建一个包含控件名称的字符串 即文本字段之一 如何使用我创建的保存文本字段名称的字符串来引用实际的文本字段 例如 我有 txt1 txt2
  • Windows Phone 8 - 2 背景音频冲突并且两个应用程序都终止

    大约一周前 我为 Windows Phone 商店提交了一个在线后台广播流应用程序 该应用程序非常好 当我使用模拟器对其进行测试时 它在所有可能的领域都很好 但是当我提交它进行认证时 它失败了 根据错误日志 如果有人已经在音乐 视频中心播放
  • 使用嵌套和根级别数据的 Elasticsearch 嵌套聚合比率

    我感觉像是一个简单的聚合 我有一个文档 其计时代码如下 task start 2020 06 03T21 19 07 908821Z task end 2020 06 03T21 27 00 323790Z sub tasks key su
  • Visual Studio 2010下LNK2019错误

    我在 Visual Studio 2010 下使用以下文件创建了一个示例 C 项目 A h ifndef A H define A H include
  • 如何正确设置 ios 标志以进行流操作?

    我在 C 中输入了一个基本示例 其中我尝试将一个数字以十六进制形式打印到屏幕上 如下所示 include
  • IEnumerable 没有 Count 方法

    我有以下方法 public bool IsValid get return GetRuleViolations Count 0 public IEnumerable
  • 与 React 之外的功能组件通信

    我希望能够从正常 HTML 中的组件外部与我的 React 组件进行通信 由于将组件嵌入到另一个系统中而需要 我一直在研究这个 我看到了您可以添加组件的建议window通过在渲染的元素上添加引用 如下所示 ReactDOM render
  • 使用 Python 生成报告:PDF 或 HTML 到 PDF

    Using maptplotlib我创建了 9 个图表 使用命令将它们组合成一个 pdfsavefig 但是我需要能够在每个图下方显示统计分析 describe 最好的方法是什么 Pandas 可以包含一张带有绘图的表格 请参阅table夸
  • 为什么 DBI 会隐式地将整数更改为字符串?

    我有一个具有以下结构的 MySQL 表 alid bigint 20 ndip varchar 20 ndregion varchar 20 occ num int 3 Delta Flag int 1 从表中选择数据后 我将获取所有引用的
  • 最后使用 Javascript 加载一些图像

    嗨 我只是想知道这是否可能 我的网站上有很多图像 我已将它们设置为尽可能小的文件大小 有些图像用作幻灯片 但全部都一次性加载 有没有一种方法使用 javascript 使幻灯片图像最后加载 以便背景图像等首先加载 幻灯片最后加载 这些图像位
  • 访问路由器参数 VueJS

    我正在使用 Vuejs 创建一个博客 而且我对它还很陌生 简而言之 我有一个加载到屏幕上的动态元素列表 当您单击其中一个项目时 我想转到该页面以及其余数据 我遵循了与使用 React 时相同的流程 路由器 js export default
  • 将 numpy 整数数组传递给 c 代码

    我正在尝试编写 Cython 代码来将密集特征矩阵 目标向量对转储为 libsvm 格式 速度比 sklearn 的内置代码更快 我收到一个编译错误 抱怨将目标向量 整数的 numpy 数组 传递给相关 c 函数时出现类型问题 这是代码 i
  • 使用 dlib 进行狗脸检测 - 需要有关改进 recal 的建议

    我正在尝试使用 dlib 的猪金字塔检测器训练狗脸检测器 我使用哥伦比亚狗数据集 ftp ftp umiacs umd edu pub kanazawa CU Dogs zip 起初我的召回率为 0 但通过增加 C 值 我设法将训练集上的召
  • 返回分配的字符串导致内存泄漏

    在 Fortran 中返回可变长度字符串的建议解决方案来自this问题 function itoa i result res character allocatable res integer intent in i character r
  • 需要密码才能禁用 Android 设备管理员

    我正在考虑一个具有设备管理员权限的安全应用程序 我想看看当用户尝试在 设置 gt 安全 gt 设备管理员 下以管理员身份取消选中该应用程序时 是否可能需要密码 这将增加一个障碍 不允许用户轻易卸载应用程序 因为他们首先需要从应用程序中删除管
  • Rails 上具有自定义域的多租户

    我正在创建像 Shopify 这样的多租户应用程序 并且想知道如何在指向同一应用程序实例的服务器上创建自定义域 例如 app1 mysystem com www mystore com app2 mystem com www killers
  • 使用变量按名称选择 ActiveX 控件复选框(在 Word 或 Excel 中)?

    这行代码有什么问题吗 WordDoc CheckBoxNum Value CheckBoxVal 需要明确的是 我正在使用 ActiveX 控件 复选框 我将值 真 假 和复选框名称保存在 Excel 文件中 该代码打开我的 Word 文档
  • 元素的最大尺寸

    我正在使用高度为的画布元素600 to 1000像素和宽度为几十或几十万像素 然而 在一定数量的像素 显然未知 之后 画布不再显示我用 JS 绘制的形状 有谁知道有没有限制 在 Chrome 12 和 Firefox 4 中进行了测试 更新
  • 如何将字符串或类传递给方法来创建实例

    我将使用以下方法 它通过向其传递类型来工作 例如obj addComponent MyClass 这很好用 我尝试修改type参数通过添加 string到它 但它现在给我错误说 不能将 new 与类型缺少调用或构造签名的表达式一起使用 无论