1

I wonder how to implement inheritance in Typescript. I make a base class Model like this:

export class Model {

  [key: string]: any;

  public errors?: {
    [key in keyof Model]: string;
  };

  constructor(model?: { [key in keyof Model]: Model[key] }) {
    if (model) {
      Object.assign<Model, Model>(this, model);
    }
  }
}

Then I write a test file like this:

import {Model} from './Model';

describe('Model', () => {
  class ChildModel extends Model {
    public name: string;
  }

  it('create model from object', () => {
    const name: string = 'Test Model';
    const childModel: ChildModel = new ChildModel({
      name,
    });
    expect(childModel.name).toEqual(name);
  });
});

I tried to debug in the base class constructor scope, the input model properties were fully mapped into the class instance. However, the child class instance can not access the mapped properties. I have searched on Google many times. All the articles say that the super call must be placed at the first line in the child class constructor. Even I tried to create a default constructor for child class with a first-line super call, the test still failed. Am I doing wrong?

I also tried to run the code and code sandbox. It works. Please clone this repository then run yarn test to see the error occurs

Cœur
  • 37,241
  • 25
  • 195
  • 267
Thanh Tùng
  • 60
  • 1
  • 6
  • I cannot reproduce your issue, please create a reproducible code sandbox. See https://codesandbox.io/s/dreamy-cannon-gqs4n – Joshua Chan Dec 08 '19 at 05:05
  • It works on Code Sandbox. The test passed. I can't understand why. Please clone this repository and run `yarn test` to see the error occurs. https://github.com/thanhtunguet/react3l-template – Thanh Tùng Dec 08 '19 at 08:13

1 Answers1

1

Fiddle around your code, I got it to work by omitting the name property in your derived class.

describe('Model', () => {
  class ChildModel extends Model { }

  it('create model from object', () => {
    const name: string = 'Test Model';
    const childModel: ChildModel = new ChildModel({
      name,
    });
    expect(childModel.name).toEqual(name);
  });
});

This is mainly due to the difference of object constructor initialization order in different compilation targets set in codesandbox (ES6) and in your case I suppose react-scripts (ES5).

You can read further in this stackoverflow thread and also this GitHub issue.

Joshua Chan
  • 1,797
  • 8
  • 16