Makla
Makla

Reputation: 10459

Typescript Partial params in constructor and access in extended class

How can I achieve this:

export class Base
{
    constructor(public defaultValues: Partial<Base>)
    {
        if (defaultValues)
            for (const [key, value] of Object.entries(defaultValues))
                this[key] = value;
    }
}

export class Extended extends Base
{
    public prop1: boolean;

    public method1()
    {
        //prop1 does not exists, because defaultValues are Base not Extended
        this.defaultValues.prop1;     //!!!! ERROR Property 'prop1' does not exists on type 'Partial<Base>'.
    }
}

I need to set some default values to class itself and store it in variable, so I can access defaultValues later.

Edited:
I also try:

class Base<T extends Base = any> {
    constructor(public defaultValues: Partial<T>) {

    }
}

class Extended extends Base<Extended> {
    public prop1: boolean;

    public method1() {
        this.defaultValues.prop1;
    }
}

But got error:

enter image description here

and this, but now I get error that

T[keyof T] is not accessible to this[keyof t]

:

export class Base<T extends Base<T>>
{
    constructor(public defaultValues: T)
    {
        if (defaultValues)
            for (const [key, value] of Object.entries(defaultValues))
                this[key] = value;  //!!!!! ERROR
    }
}

export class Extended extends Base<Extended>
{
    public prop1: boolean;

    public method1()
    {        
        this.defaultValues.prop1; 
    }
}

Error with default parameters:enter image description here

Edited 3:
After installing VS 15.3 (VS 2017 update 2) and Typescript SDK 2.3 and after choosing Typescript 2.3 in Intellisense for VS 2017 I made some progress. Have just a little tiny problem:enter image description here

Upvotes: 1

Views: 901

Answers (1)

Nitzan Tomer
Nitzan Tomer

Reputation: 164167

Base doesn't have a member called prop1, Extended does.
You can make Base generic:

class Base<T extends Base = any> {
    constructor(public defaultValues: Partial<T>) {
        ...
    }
}

class Extended extends Base<Extended> {
    public prop1: boolean;

    public method1() {
        this.defaultValues.prop1;
    }
}

Edit

Before typescript 2.3 (because of Generic parameter defaults) you need to do:

class Base<T extends Base<any>> {
    constructor(public defaultValues: Partial<T>) {

    }
}

2nd edit

If you're using the noImplicitAny flag then you need to do this:

class Base<T extends Base<any>> {
    constructor(public defaultValues: T) {
        if (defaultValues) {
            for (const [key, value] of Object.entries(defaultValues)) {
                this[key as keyof this] = value;
            }
        }
    }
}

The difference being this[key as keyof this] = value;

Upvotes: 1

Related Questions