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;