B
B
BonBon Slick2020-05-24 14:03:48
typescript
BonBon Slick, 2020-05-24 14:03:48

How to properly initialize class properties?

export default class Menu extends Vue {
    private menuItems: Item[];

    public constructor() {
        super();
        this.initMenuItems();
    }

    private initMenuItems() {
        let item = new Item();
        item.title = 'Home';
        this.menuItems.push(item);
        let item2= new Item();
        item2.title = 'Login';
        this.menuItems.push(item2);
    }


TS2564: Property 'menuItems' has no initializer and is not definitely assigned in the constructor.


And if so
public constructor() {
        super();

        let item = new Item();
        item.title = 'Home';
        this.menuItems.push(item);
        let item2 = new Item();
        item2.title = 'Login';
        this.menuItems.push(item2);
    }

then
TS2565: Property 'menuItems' is used before being assigned.

the second case decided like this
private menuItems: Item[] = [];

Why so?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
T
twoone, 2020-05-31
@BonBonSlick

This behavior is possible due to a combination of such compiler options as --strictNullChecksand --strictPropertyInitialization, the first of which prohibits the assignment of null and undefined as values ​​(provided that they were not specified in the type annotation), and the second flag transfers the behavior of the first to class fields.
If in javascript (and in general, it seems to me everywhere) to initialize the class fields at the place of declaration, then in fact it will happen in the constructor. Therefore, the typescript compiler does not consider it an error to assign values ​​to uninitialized fields in a constructor. But a method called from a constructor is not considered valid.
As a solution, it is proposed to use the definite assignment assertion modifier, which is specified before the colon preceding the type annotation and shifts the responsibility for possible incidents associated with null or undefined values ​​to the developer.
In your case it will look like this -

class Menu extends Vue  {
    private menuItems!: Item[]; // восклицательный знак перед двоеточием

    public constructor() {
        this.initMenuItems();
    }

    private initMenuItems() {
        let item = new Item();
        item.title = 'Home';
        this.menuItems.push(item);
        let item2= new Item();
        item2.title = 'Login';
        this.menuItems.push(item2);
    }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question