vue-class-component : how to create and initialize reflective data vue-class-component : how to create and initialize reflective data typescript typescript

vue-class-component : how to create and initialize reflective data


A correct type for such property is:

private data: Model | null = null;

It can be used with type guards:

if (this.data) {  console.log(this.data.name); // Model}

Or non-null assertion operator:

console.log(this.data!.name); // Model

A workaround is to cheat typing system with assertion:

private data: Model = null as unknown as Model;

vue-class-component doesn't take TypeScript into account because undefined is easier to handle in TypeScript than null, particularly because this would allow to mark a property as optional.

I know that data will never be null.

It will be null until the component is mounted, this leaves a room for mistake:

public created() {    console.log(this.data.name); // runtime error but no compilation error}public mounted() {    this.data = {...this.$store.getters.data};}


You can use a getter instead of assigning the data directly, assuming the data is set in the store when it is created. Make sure your store getters are typesafe!

@Componentexport default class ClubVue extends Vue {    private _data: Model | undefined;    get data(): Model {        if (!this._data) {            this._data = {...this.$store.getters.data};        }        return this._data;    }}

This way, data will never be undefined, since it will either return _data or set _data to the current store content and then return that.
This may fail if _data is a primitive instead of an object, and evaluates to false (e.g. (Number)0 or (String)""). In that case, use this._data === undefined instead of !this._data.

You can also shorten the getter to

get data():Model {    return this._data = this._data || {...this.$store.getters.data};}

but this is less clear, especially if the reader is not aware that an assignment will return the value/reference that is being assigned, and even worse to read with primitive types:

return this._data =     this._data === undefined         ? {...this.$store.getters.data}         : this._data;