基于类和子类属性的Typescript构造函数参数

px9o7tmv  于 11个月前  发布在  TypeScript
关注(0)|答案(2)|浏览(149)

让我们假设我希望在子类中重用一些基本的构造函数,但它的参数将取决于子类的属性。
这里有一个基本的(非工作)例子,我试图实现。

class Foo {
    a: string = 'a'

    constructor(params?: { [key in keyof this]: this[key] }) { // this doesn't work as 'this' is not permited static members. 
        Object.assign(this, params)
    }
}

class Bar extends Foo {
    b: string = 'b'

    // constructor inherited accepting { a: string, b: string }
}

const myFoo = new Foo({ a: 'foo' })
const myBar = new Bar({ a: 'foo', b: 'bar' })

字符串
在TS中有什么方法可以做到这一点吗?
操场

acruukt9

acruukt91#

对于Foo,您可以使用params?: Foo,然后new Foo({a: "ayy"})将工作,但Bar将期望Foo,而不是Bar
不幸的是,我认为除了在Bar中提供一个构造函数之外,没有什么可以改变的。当然,这个构造函数不需要做太多的事情,只要super(params)就可以了。

class Foo {
    a: string = "a";

    constructor(params?: Foo) {
        Object.assign(this, params);
    }
}

class Bar extends Foo {
    b: string = "b";

    constructor(params?: Bar) {
        super(params);
    }
}

字符串
Playground链接
如果params?: typeof this(或它的其他衍生物)可以工作(并处理子类之间的含义变化),那就太好了,但目前情况并非如此。

xmd2e60i

xmd2e60i2#

也许不是你想要的,但是你可以使用泛型。当定义一个新的子类时,子类类型将作为泛型传递给基类。

type NonFunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K;
}[keyof T];
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;
type DefaultFoo = Foo<any>;

class Foo<T extends Foo = DefaultFoo> { // Can't default to Foo here, it errors: Type parameter 'T' has a circular default.(2716)
    a: string = 'a'

    constructor(params?: Partial<NonFunctionProperties<T>>) {
        Object.assign(this, params)
    }
}

class Bar extends Foo<Bar> {
    b: string = 'b'
}

new Foo({ a: 'foo' }) // no error
new Bar({ a: 'foo', }) // no error
new Bar({ a: 'foo', b: 'bar' }) // no error
new Foo({ b: 1 }) // error: Object literal may only specify known properties, and 'b' does not exist in type 'Partial<NonFunctionProperties<DefaultFoo>>'.
new Bar({ a: 1 }) // error: Type 'number' is not assignable to type 'string'.
new Bar({ ab: '' }) // error: Object literal may only specify known properties, and 'ab' does not exist in type 'Partial<NonFunctionProperties<Bar>>'.

字符串
TypeScriptPlayground
有关NonFunctionProperties的详细信息,请参阅此

相关问题