【问题标题】:How to add dynamic properties to TypesScript class and maintain correct typings如何向 Typescript 类添加动态属性并保持正确的类型
【发布时间】:2019-10-04 06:27:59
【问题描述】:

我有一个 Users 类,我从文件 Users.ts 导出

    export default class Users {}

然后我从另一个文件index.ts 导出Users.ts

    // classes
    export {default as Users} from './Users'

我有第三个文件Foo.ts,我想在其中动态实例化从index.ts 导出的所有类,并将它们作为属性添加到该类:

    import * as classes from './index'

    class Foo {
        constructor() {
           const httpClient = new HttpClient()
        }

        _addClasses() {
           for (const class in classes) {
             this[class] = new classes[class](this.httpClient);
           }
        }
    }

我的问题是,如何将正确的类型添加到 Foo,以便在 IDE 中为 .users 获得正确的自动补全,例如:

new Foo(new HttpClient).users

【问题讨论】:

  • 我在任何地方都看不到属性 .users 的任何定义,除非您尝试使用它。而你的 Foo 构造函数不带任何参数。
  • 没错,我要推断类型。
  • @Nit 你是对的,但我希望避免创建包装函数 + 类型强制。

标签: typescript typescript-typings typescript2.0


【解决方案1】:

这个问题的第一部分是创建一个包含导入模块的实例类型的新类型。为此,我们将使用预定义的条件类型InstanceType 来提取类的实例类型。要获取模块的类型,我们将使用typeof classes。将它全部包装在一个映射类型中,我们得到:

type ClassInstances = {
    [P in keyof typeof classes]: InstanceType<typeof classes[P]>
}

// For the example above this is equivalent to 
type ClassInstances = {
    Users: classes.Users;
}

现在我们需要将这些新属性添加到类中。要做到这一点而不显式定义它们,我们可以使用一个空类表达式作为Foo 的基类,并断言这个空类返回的实例具有这些成员(实际上并没有,但我们和这些成员在@ 987654325@ 所以一切都解决了)。综上所述,我们得到:

import * as classes from './index';

type ClassInstances = {
    [P in keyof typeof classes]: InstanceType<typeof classes[P]>
}

class Foo extends (class {} as new () => ClassInstances) {
    httpClient: HttpClient;
    constructor() {
        super();
        this.httpClient = new HttpClient()
        this._addClasses();
    }

    _addClasses() {
        for (const cls of Object.keys(classes) as Array<keyof typeof classes>) {
            this[cls] = new classes[cls](this.httpClient);
        }
    }
}

new Foo().Users // ok now name is the same as the name used in the export in index.ts so it's upper case. No string manipulation on string properties.

【讨论】:

    猜你喜欢
    • 2022-07-21
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 2022-11-24
    • 1970-01-01
    相关资源
    最近更新 更多