TypeScript:自动生成的动态函数名称

Ada*_*dam 9 javascript types typescript

我在TypeScript中有一些动态生成的函数名.我现在可以使用它们的唯一方法是将对象投射到<any>.例如:<any>myInstance.getDataA().这些函数是根据某些规则动态生成的.基于相同的规则,我想为我的classes 生成类型定义,但我无法使其工作.

original.ts

abstract class Original {

    dynamics = ['getData', 'setData'];

    constructor() {
        // I create functions here dynamically
        this.dynamics.forEach((key) => {
            this[key + this.info] = () => null;
        });
    }

    get info() {
        return 'X';
    }
}
Run Code Online (Sandbox Code Playgroud)

我-class.ts

class MyClass extends Original {
    get info() {
        return 'A';
    }
}
Run Code Online (Sandbox Code Playgroud)

我 - 其他 - class.ts

class MyOtherClass extends Original {
    get info() {
        return 'B';
    }
}
Run Code Online (Sandbox Code Playgroud)

something.ts

const myInstance = new MyClass();
console.log(myInstance.getDataA()); // TS2339: Property getDataA does not exist on type: 'MyClass'

const myOtherInstance = new MyOtherClass();
console.log(myInstance.getDataB()); // TS2339: Property getDataB does not exist on type: 'MyClass'
Run Code Online (Sandbox Code Playgroud)

我想自动生成一个定义文件来定义这些动态属性.

例:

我-class.def.ts

 declare interface MyClass {
    getDataA;
    setDataA
 }

 //my-other-class.def.ts
 declare interface MyClass {
    getDataB;
    setDataB
 }
Run Code Online (Sandbox Code Playgroud)

但我无法找到定义文件的语法以使其工作.请问我是否不清楚,如果您有任何想法,请帮忙!

Tit*_*mir 6

内部语言方法

在类型系统中无法做到这一点,因为我们无法对字符串文字类型执行字符串操作.在没有外部工具的情况下,您可以获得的最接近的get/set方法是创建采用字符串文字类型的getInfo方法,该方法与方法返回的类型相同.

function stringLiteralArray<T extends string>(...v: T[]){ return v;}

abstract class Original {
    get(name: this['info'][number]) {
        return null;
    }

    set(name: this['info'][number], value: any) {
        return null;
    }

    get info() : string[]{
        return [];
    }
}

class MyOtherClass extends Original {
    get info() {
        return stringLiteralArray('A', 'B', 'ABAB');
    }
}
class MyClass extends Original {
    get info() {
        return stringLiteralArray('C', 'D', 'DEDE');
    }
}

let s =new MyClass();
s.get('A') // error 
s.get('C') // ok
Run Code Online (Sandbox Code Playgroud)

虽然这种方法不是你想要的100%,但是从我们之前的讨论开始,我们的目标是为这些方法提供完整的代码完成,而这种方法可以实现这一目标.如果传入错误的值并获得字符串的完成列表,则会出现错误:

在此输入图像描述

编译器API方法

第二种方法是创建一个自定义工具,使用typescript 编译器API来解析ts文件,查找派生自的类,Original并生成包含这些方法的接口(在同一个文件或不同的文件中),如果您感兴趣的话我可以编写代码,但这并不简单,虽然编译器API是稳定的,但我认为编译器团队不会像使用语言那样关注向后兼容性(实际上这是他们制作的确切语句)在文档页面中).

如果您对这样的解决方案感兴趣,请告诉我,我可以提供,但我建议不要这样做.