Is it possible to modify a TypeScript interface without using inheritance?

Working with a library called vue-i18n, I came across the following declaration in its types/index.d.ts file (edited for brevity):

declare class VueI18n {
  t(key: VueI18n.Path, values?: VueI18n.Values): VueI18n.TranslateResult;
  t(key: VueI18n.Path, locale: VueI18n.Locale, values?: VueI18n.Values): VueI18n.TranslateResult;
}

declare module 'vue/types/vue' {
  interface Vue {
    $t: typeof VueI18n.prototype.t;
  }
}

I'm interested in changing the return type of the t function from TranslateResult to a string without extending it into a new interface. To achieve this, I tried creating a custom declarations.d.ts file:

import VueI18n from 'vue-i18n';

declare module 'vue/types/vue' {
  interface Vue {
    $t(key: VueI18n.Path, values?: VueI18n.Values): string;
    $t(
      key: VueI18n.Path,
      locale: VueI18n.Locale,
      values?: VueI18n.Values
    ): string;
  }
}

However, I encountered an error:

[ts] Duplicate identifier '$t'.

Is there a way to modify the existing type without extending it or creating a new interface? Any suggestions?

EDIT:

It seems like in-place override may not be possible. How can I avoid repeating as string when using $t function?

this.msg = this.$t('blah') as string;
this.str2 = this.$t('thisToo') as string;
this.strX = this.$t('another') as string;
this.g = this.$t('test') as string;

Answer №1

It appears that reducing the repetitiveness of using a string here is not possible at this time. Is there a way to streamline this process?

Utilizing a Mixin for Simplified $t Usage

test-i18n.mixin

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

@Component
export default class LangMixin extends Vue {

  public t(key: string, params?: string[]) {
    return this.$t(key, params) as string;
  }
}

Incorporate the mixin into any component and utilize this.t instead of this.$t: eliminating the need to cast $t in each call.

<template>
  <p>{{someStringProperty}}</p>
</template>

<script lang="ts">
import {Mixins, Component} from 'vue-property-decorator';
import langMixin from './test-i18n.mixin';

@Component
export default class LangTest extends Mixins(langMixin) {

  get someStringProperty(): string {
    return this.t('global.last-name');
  }
}
</script>

While I am utilizing vue class components, this approach is compatible with Vue.extend as well. However, it is highly recommended that when using mixins, opt for the class component api to avoid losing valuable intellisense/types assistance.

(Don't forget to apply the same method with $tc).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Vue: Implementing conditional styling in table cells

Currently, my vue function involves using nested v-for loops to iterate through an object and create a table with rows and cells. While this method is effective, I am now faced with the challenge of implementing a v-if statement in the innermost loop to co ...

Extending Record in Typescript: A Comprehensive Guide

When working on interfaces, I often find myself wanting to extend the type Record in order to define objects with predefined keys and optional values without knowing their names. For instance: interface Person extends Record<string, string>{ phonen ...

Learning to implement Angular's two-way binding with the directionsService.route() function in Google Maps

Check out my Angular Component export class MapsComponent implements OnInit { @ViewChild('googleMap') gmapElement: any; map: google.maps.Map; data = "initialized"; ngOnInit() { var directionsService = new google.maps.DirectionsSe ...

Using Angular's setTimeout() function with an external lambda that includes a parameter

My goal is to tackle two issues at once: 1) using setTimeout( #action#, timeMillis) with #action# as a lambda 2) supplying the lambda with a parameter. The common method of setTimeout( ()=>{ #callback# }, timeMillis) works flawlessly when extracting () ...

Using v-tooltip from vuetify causes the entire page to malfunction

Currently, I am utilizing this code snippet sourced from the Vuetify documentation: <v-tooltip bottom> <template #activator="data"> <v-btn color="primary" dark v-on="data.on">Button</v-btn> ...

Error in React 16.3 Context: The anticipated input for built-in components should be a string, while for composite components it should be a class or function. However, an

I am fairly new to React, so this issue may be quite simple. Essentially, I have been attempting to utilize modals with Context. I have set up my Context in a separate file: import { createContext } from 'react'; export const ModalContext = cr ...

The JSON format is invalid because it contains an unexpected token "o" pointed to by the "Blob" object

I've been experimenting with a video chat code that I stumbled upon on YouTube. However, every time I try to make a call, I encounter an error. It's been a few days now and I can't seem to pinpoint where the issue lies. Here is the snippet ...

What is preventing me from accessing the additional JavaScript functions in Vue Laravel?

After stumbling upon a code snippet online that utilized a class without specifying whether it was for Vue or JavaScript, I decided to test it out. However, I encountered an issue where I couldn't access any functions after importing the class. I bel ...

Data will not bind with Laravel and Vue

I am currently working on a Laravel project and trying to develop a basic editing feature for posts. My approach involves using Vue.js 2 to bind the data, but unfortunately, I am facing issues with displaying it - I'm not quite sure what's causin ...

The NextRouter failed to mount in Next.JS

When you use import { useRouter } from "next/router"; instead of import { useRouter } from "next/navigation";, it results in the error message "Argument of type '{ pathname: string; query: { search: string; }; }' is not assign ...

"Error: The update depth has exceeded the limit while trying to use the

I've been working on implementing localStorage in NextJs using TypeScript by following this guide at , but I am encountering an error. https://i.sstatic.net/NX78a.png Specifically, the error occurs on the context provider repeatedly. Below is the c ...

Navigating Rails Active Storage in a VueJS Blog

Utilizing Active Storage in a Rails 5.2 application with AWS S3 for image hosting has been successful when using <%= image_tag @gin.pic %> in an HTML view. However, I am encountering difficulties with the file path while integrating a separate VueJS ...

Problem encountered when executing "npm run dev" in Vue.js with vue-cli

My current setup: Running Centos7 on VirtualBox (host OS : Windows 7) Node version: 6.10.3 Npm version : 3.10.10 Operating behind a corporate proxy I went ahead and installed vue-cli using the following command: sudo npm install -g vue-cli After that, ...

Create a NfcV Write Lock Block instruction

Seeking to make data on a NXP ICODE SLIX SL2S2002 tag type 5 (ISO 15693) read-only by utilizing the WRITE SINGLE BLOCKS command through the NfcV object in an app based on Ionic: private readonly cmdISO15693 = { READ_SINGLE_BLOCK: 0x20, WRITE_SI ...

Updating a data value in Vue3 also updates the corresponding prop

Not sure if this is standard behavior, I'm fairly new to Vue, but it's really frustrating. Hopefully someone here can shed some light on what's going on... Here's my code snippet: props: [ 'asset', //--- asset.price = 50 ...

Exploring the versatility of Vue.js through props and scoped slots

Coming from a React background, I am used to being able to easily alter children components before they render. However, after spending hours reading the VueJS documentation and searching forums, I have not been able to find a straightforward way to do thi ...

How does [name] compare to [attr.name]?

Question regarding the [attr.name] and [name], I am utilizing querySelectorAll in my Typescript as shown below: this._document.querySelectorAll("input[name='checkModel-']") However, when I define it in the HTML like this: <input [name]="check ...

Is it feasible to activate a function when certain Vue data elements are altered?

Looking to monitor a set of data elements for changes and then save them in localStorage. Is there an easy way to achieve this? ...

Is it possible to toggle between namespace and class using parentheses?

While working with older javascript code, I stumbled upon the following snippet: // module1.js class Class { constructor() { console.log('hello') } } const exported = { Class: Class, } module.exports = exported This code is then ...

VueJS form validation does not account for empty inputs in both fields

One of the challenges I'm facing is generating a form with Vue.js using the input fields below: { name: 'first_name', type: 'text', label: 'First Name', placeholder: 'First Name', ...