根据输入数据使用括号表示法

时间:2019-06-05 00:40:39

标签: javascript node.js typescript

我正在优化库中的某些代码,但是,在尝试调用导入的类时为什么括号表示法不起作用存在一些问题。

参数type接受驼峰式字符串,例如:myString。 参数data可以是任何值。

import { foo } from './example';

export const find = (type: string, data: any) => {

// This next line effectively deletes the end of the string starting
// from the first capital letter.
    const f = type.replace(/[A-Z][a-z]+/, '');
    try {
        return [f][type](data);
    } catch (e) {
        return e;
    }
};

如果我使用点表示法将其可视化,这就是我期望的样子:

foo.fooBar(someRandomData)

这应该在导入的类fooBar(data)上调用静态方法foo, 但是,我收到一条错误消息:

TypeError: [f][type] is not a function

如果我将其还原为我的if..else if样式,它会起作用:

if (type.startsWith('foo')) return foo[type](data);

如何在没有得到定义的错误消息的情况下完成上述操作?

谢谢您的帮助!

  

编辑:这是我从现有代码中修改的一个示例,因此,我修复了一些错字。

     

编辑#2:根据要求,导入的类foo如下所示:

export class foo{
static fooBar(data){
// Do stuff with data...
}

2 个答案:

答案 0 :(得分:0)

我建议您改为使用内置的EventEmitter的nodeJS。

您可以执行以下操作:

import * as EventEmitter from 'events';

import { foo } from './example';
import { bar } from './example2';

export const discordEventEmitter = new EventEmitter();

discordEventEmitter.on('fooBar', foo.fooBar);
discordEventEmitter.on('fooToo', foo.fooToo);
discordEventEmitter.on('barBell', bar.barBell);

然后,当您要触发事件时,只需:

discordEventEmitter.emit('fooBar', someData);

您还可以通过以下方式简化事件处理程序的注册:

const fooProps = Object.getOwnPropertyNames(foo) as (keyof typeof foo)[];
fooProps.filter(k => typeof foo[k] === 'function').forEach(funcName => {
  discordEventEmitter.on(funcName, foo[funcName]);
});

const barProps = Object.getOwnPropertyNames(bar) as (keyof typeof bar)[];
fooProps.filter(k => typeof bar[k] === 'function').forEach(funcName => {
  discordEventEmitter.on(funcName, bar[funcName]);
});

答案 1 :(得分:0)

最后,您需要对开始使用的类或对象的一些引用。这是一个如何实现这种功能的有效示例,但是您已经从类实例的映射开始,以便可以使用它们:

class foo {
    fooBar(data: any) { return { name: 'foo', data } };
}

class example {
    exampleFood(data: any) { return { name: 'example', data } };
}

var lookup: { [classes: string]: any; } = { };
lookup['foo'] = new foo();
lookup['example'] = new example();

const find = (encodedType: string, data: any) => {
    // This next line effectively deletes the end of the string starting
    // from the first capital letter.
    const f = encodedType.replace(/[A-Z][a-z]+/, '');
    try {

        return lookup[f][encodedType](data);
    } catch (e) {
        return e;
    }
};

alert(JSON.stringify(find("fooBar", "Found you foo")));
alert(JSON.stringify(find("exampleFood", "Found you example")));