'How should Vue filters be bound using typescript?

How should Vue filters be bound using TypeScript? It is fairly straightforward with pure js, but I'm running into issue converting it to TypeScript.

The code and compile error are as follows:

app.ts

import * as Vue from 'vue'
...
import * as filters from './util/filters'

// register global utility filters.
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key]);
})

util/filters.ts

export function host (url: string) {
  ...
}

export function timeAgo (time: any) {
  ....
}

Compile Error

error TS7017: Element implicitly has an 'any' type because type 'typeof ...' has no index signature.



Solution 1:[1]

I'm using a library called vue-property-decorator where you can do something like:

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

@Component({
  name: 'ComponentName',
  filters: {
    filterName(value: any) {
      return 'Hello filter'
    }
  }
})
export default class ComponentName extends Vue {
  textToFormat = 'Hello world'
}

Then to apply the filter:

<p>{{ textToFormat | filterName }}</p>

Happy coding!

Solution 2:[2]

I register global filters like this:

Inside plugins/filters.ts:

import { VueConstructor } from 'vue/types/umd'

export default {
  install (Vue: VueConstructor) {
    Vue.filter('someFormatFunc1', function someFormatFunc1(value) {
      // Your formatting function
    })
    Vue.filter('someFormatFunc2', function someFormatFunc2(value) {
      // Your formatting function
    })
  }
}

Then inside main.ts:

import filters from './plugins/filters'
Vue.use(filters)

Solution 3:[3]

For adding the filter globally, I did something as following

// in customFilter.ts file

import Vue from 'vue';

const testFilter = Vue.filter(
  'filterName', () => {
    // filter fn
   }
);
export default testFilter;

and include this in main.ts

import testFilter from '@/customFilter.ts'

new Vue({
...
  filters: {
    testFilter
  },
...

Solution 4:[4]

This works for me (Vue2 + TypeScript):

Define filters in filters.ts

export default ({
  filterName1(value: any) { return 'Hello filter 1' },
  filterName2(value: any) { return 'Hello filter 2' }
} as { [key: string]: any })

and then, register filters globally in main.ts

import Vue from 'vue'
import App from './App.vue'
import filters from '@/filters'

// register filters
Object.keys(filters).forEach(key => { Vue.filter(key, filters[key]) }) 

new Vue({store, render: h => h(App)}).$mount('#app')

Hope this could help ?

Solution 5:[5]

In this case your can simple use Type Assertion

Object.keys(filters).forEach(key => {
  Vue.filter(key, (filters as any)[key])
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Second Technologies
Solution 2 rockstarr-programmerr
Solution 3 Sanju
Solution 4 gurigurico
Solution 5 user5639065