首页 > 解决方案 > 如何在 Typescript 中模仿 Python 中的 kwargs

问题描述

所以我正在用打字稿建立一个小型图书馆。有一个基类可以继承多个类。该类base有许多属性可以作为参数在构造函数中传递,可以有默认值。问题是,是否必须base在每个子类的构造函数中提供这些类属性?

例子:

class BaseClass {
    constructor(a: number, b: number, c: number, d: number) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
    private a: number;
    private b: number;
    private c: number;
    private d: number;
}

class SubClass extends BaseClass {
    constructor(a: number, b: number, c: number, d: number, e: number, f: number) {
        super(a, b, c, d);
        this.e = e;
        this.f = f;
    }
    private e: number;
    private f: number;
}

是否有任何方法可以减少冗长,例如 pythonkwargs在调用 super in 时可以使用__init__

标签: pythontypescriptoop

解决方案


是的,您可以将工作方式类似的对象传递给 kwargs。我在 aws CDK 中看到了类似的编码风格,现代 ecmascript 标准(以及连续的打字稿)似乎与这种方法很好地配合,因为对象解构现在是一等公民。例如:

    interface BaseClassKwargs{
      a: number;
      b: number;
      c: number;
      d: number;
    }
    interface SubClassKwargs extends BaseClassKwargs{
      e: number;
      f: number;
    }
    class BaseClass {
        constructor(kwargs:BaseClassKwargs) {
            this.a = kwargs['a'];
            this.b = kwargs['b'];
            this.c = kwargs['c'];
            this.d = kwargs['d'];
        }
        private a: number;
        private b: number;
        private c: number;
        private d: number;
    }
    class SubClass extends BaseClass {
        constructor(kwargs:SubClassKwargs) {
            super(kwargs);
            this.e = kwargs['e'];
            this.f = kwargs['f'];
        }
        private e: number;
        private f: number;
    }

并且利用重组甚至可以写成:

    class BaseClass {
        constructor({a, b, c, d}:BaseClassKwargs) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
        }
        private a: number;
        private b: number;
        private c: number;
        private d: number;
    }
    class SubClass extends BaseClass {
        constructor({e,f, ...kwargs}:SubClassKwargs) {
            super(kwargs);
            this.e = e;
            this.f = f;
        }
        private e: number;
        private f: number;
    }

在 aws cdk 中,它们不被称为 kwargs,它们被称为道具,但无论名称如何,心态都是相似的。

请注意,对于具有默认值,甚至可以涵盖将完整对象及其属性都具有默认值的极端情况:

constructor({ a = 1, b = 0, c = -1, d = -2 } = {}): void {
  // ...
}

具有相似编码风格的示例项目

关于解构的打字稿文档


推荐阅读