Vue + Typescript "meteor:" type definition

OK, so I’ve got typescript + meteor + VueJs kinda working.

But is there an official (global) way to extend the Vue type definition so it understands the "meteor:" property?

image

FYI, I’m using:

# For .ts files
meteor add typescript
meteor npm install --save-dev @types/meteor
# and for Vue files.
meteor add nathantreid:vue-typescript-babel
# which needs...
meteor npm install --save-dev @babel/plugin-transform-typescript

Thanks!

OK, so for anyone else who’s interested, here’s the solution I’ve come up with. It’s not automagic, but doesn’t require much extra code.

First, the easy bit: allowing the component definition to have a random meteor: property and define the extra properties added to the Vue component ($subscribe, etc). Just put this somewhere:

declare module 'vue/types/options' {
    interface ComponentOptions<V extends Vue> {
        meteor?: any;
    }
}

declare module 'vue/types/vue' {
    interface Vue {
        $subscribe: (name: string, params: any[]) => void;
        $autorun: (fn: () => void) => number;
        $subReady: Record<string, boolean>;
  }
}

Then the tricky bit: allowing data/subscriptions defined within the meteor: property to be correctly typed. Help came via this StackOverflow answer: https://stackoverflow.com/a/60948413/9614402

Just define this function somewhere:

export const withMeteorData = <TData>(data: TData) => {
	return <TMeteorData>() => data as TData & MeteorData;
}

Then, import it into in any Vue component which uses meteor:, then:

data() {
    return withMeteorData({
        // normal reactive data goes here
        loading: false,
    })<{
        // stuff defined in meteor: goes here to get added to the component's types
        apiKey: string;
    }>()
},
meteor: {
    $subscribe: {
        'users_api_key': () => { return [Meteor.userId()]},
    },
    apiKey() {
        return Meteor.users.findOne(Meteor.userId()!, {fields: {apiKey: 1}})!.apiKey || '';
    },
},

If anyone can find a better/automatic solution then please let us know!

This way of setting things up seems to be longer working and we face an issue when it comes to integrating Vue Class Component. Can you please help us out?

Sorry, I don’t really have experience yet of vue-class-component.

All I know is that my combination of packages is working well on a couple of projects with Meteor 1.9:

// /package.js
  "dependencies": {
    "@babel/runtime": "^7.12.5",
    "babel-runtime": "^6.26.0",
    "vue": "^2.6.12",
    "vue-meteor-tracker": "^2.0.0-beta.5",
    "vue-router": "^3.1.6",
    "vue-server-renderer": "^2.6.12",
    ...
  "devDependencies": {
    "@babel/plugin-transform-typescript": "^7.12.1",
    "@types/meteor": "^1.4.64",
    "typescript": "^4.0.5",
    ...
// /.meteor/versions
akryum:vue-component@0.15.2
akryum:vue-component-dev-client@0.4.7
akryum:vue-component-dev-server@0.1.4
akryum:vue-pug@0.1.3
akryum:vue-sass@0.1.2
babel-compiler@7.5.1
babel-runtime@1.5.0
ecmascript@0.14.1
ecmascript-runtime@0.7.0
ecmascript-runtime-client@0.10.0
ecmascript-runtime-server@0.9.0
nathantreid:vue-typescript-babel@1.0.3
typescript@3.7.6
...

1 Like

I’ve tried running your steps when creating your project and added the dependencies you mentioned. This works correctly if using Vue.extend but not if I add vue-class-component and try using Class-Style Vue Components like is mentioned here.

Error

Exception in callback of async function: ReferenceError: TemplatingTools is not defined
    at throwCompileError (packages/vue-component/plugin/utils.js:200:15)
    at VueComponentTagHandler.getResults (packages/vue-component/plugin/tag-handler.js:104:11)
    at compileTags (packages/vue-component/plugin/vue-compiler.js:532:18)
    at compileOneFileWithContents (packages/vue-component/plugin/vue-compiler.js:541:12)
    at hotCompile (packages/vue-component/plugin/vue-compiler.js:347:23)
    at runWithEnvironment (packages/meteor.js:1286:24)
[vue-component] Error while compiling in tag <script> using lang ts Cannot read property 'data' of null
TypeError: Cannot read property 'data' of null
    at typescriptHandler (packages/vue-component-typescript-babel/vue-typescript.js:22:22)
    at packages/meteor.js:306:21
    at VueComponentTagHandler.getResults (packages/vue-component/plugin/tag-handler.js:91:26)
    at compileTags (packages/vue-component/plugin/vue-compiler.js:532:18)
    at compileOneFileWithContents (packages/vue-component/plugin/vue-compiler.js:541:12)
    at hotCompile (packages/vue-component/plugin/vue-compiler.js:347:23)
    at runWithEnvironment (packages/meteor.js:1286:24)
1 Like

@harry97 @wildhart I’ve created a new topic here for setting up meteor with Class Style Vue Components. Hopefully it will be of help for people who find this question.

1 Like