1

I'm getting an typescript error when using vue.js with the moment.js library with vue decorators. It only occurs inside the prop section of the class.

import * as moment from 'moment';

import { Vue, Component, Watch, Prop } from 'vue-property-decorator';

@Component({
  name: 'TestMoment',
  props: {
    tomorrow: moment.Moment,
  }
})
export default class TestMoment extends Vue {
  private date: moment.Moment = moment();
  public created() {
    console.log(this.date);
  }
}

The specific error is on the tomorrow property and I get:

Property 'Moment' does not exist on type 'typeof moment'. Did you mean 'isMoment'?

I have an editor which highlights errors and mousing over the moment on the line with tomorrow indicates the error, but not on the line private date...

2 Answers 2

1

The type of a VueJS prop must be a native constructor: in this case, you should be using Object instead, i.e.:

@Component({
  name: 'TestMoment',
  props: {
    tomorrow: Object,
  }
})

The tomorrow prop is typeof object and is an instance of moment, so you can perform the following check using the more declarative @Prop decorator instead, by supplying a custom validator function:

import * as moment from 'moment';
import { Vue, Component, Watch, Prop } from 'vue-property-decorator';

@Component({
  name: 'TestMoment',
  props: {
    tomorrow: moment.Moment,
  }
})
export default class TestMoment extends Vue {
  @Prop({ type: Object, validator: moment.isMoment })
  public readonly tomorrow!: moment.Moment;

  private date: moment.Moment = moment();
  public created() {
    console.log(this.date);
  }
}

You can also choose to hint TypeScript on the type of the returned object, using type: Object as () => moment.Moment:

import * as moment from 'moment';
import { Vue, Component, Watch, Prop } from 'vue-property-decorator';

@Component({
  name: 'TestMoment',
})
export default class TestMoment extends Vue {
  @Prop({ type: Object as () => moment.Moment, validator: moment.isMoment })
  public readonly tomorrow!: moment.Moment;

  private date: moment.Moment = moment();
  public created() {
    console.log(this.date);
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Moment constructor function isn't exported from the package and kept private. Moment is an interface and don't exist at runtime, while it should exist in order to provided as property value:

  props: {
    tomorrow: moment.Moment,
  }

Moment object can be naturally provided as a prop with a validator:

  props: {
    tomorrow: {
      type: Object,
      validator: moment.isMoment
    }
  }

And it's possible to extract Moment constructor to make props pass instanceof runtime checks:

const Moment = moment.fn.constructor as { new(): typeof moment };

...

  props: {
    tomorrow: Moment,
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.