During my transition from Vue2/JavaScript to Vue3/TypeScript, I encountered a difficulty with migrating a computed property that remaps component listeners to child components based on a prefix. In Vue2/JavaScript, the computed property looked like this:
inputPortListeners() {
return reduce(
this.$listeners,
(listeners, listener, name) => {
if (!name.startsWith('input-')) return listeners;
listeners[name.slice('input-'.length)] = (e) => listener.call(this, e, this.node.id, e.target.dataset.index);
return listeners;
},
{}
);
},
In Vue3/TypeScript, I attempted to migrate it as follows:
type Listeners = Record<string, (e: unknown)=>void>;
const inputPortListeners = computed(() => {
return Object.keys(attrs).reduce<Listeners>((listeners, name: string) => {
if (!name.startsWith('onInput')) return listeners;
listeners[name.replace('onInput', '')] = (e: unknown) => attrs[name].call(this, e, this.node.id, e.target.dataset.index);
return listeners;
}, {});
});
The specific issue lies in this line of code:
(e: unknown) => attrs[name].call(this, e, props.node.id, e.target.dataset.index);
This is problematic because attrs
does not have a strong type and e
is of type unknown, which prevents access to e.target.dataset.index
.
What are some possible solutions for resolving this concern?