1

I am extending the typescript String interface in my Angular app. I have added a method translate() which is accessible throughout my app. I do not get any compile errors.

However, I get a runtime error:

"TypeError: "Translate this string".translate is not a function"

Any ideas what I might be doing wrong?


Here are the screenshots of my implementation:

Declaration:

enter image description here

Implementation

enter image description here

Calling:

enter image description here

FAISAL
  • 33,618
  • 10
  • 97
  • 105
  • I don't see any [extends](https://www.typescriptlang.org/docs/handbook/classes.html) here, just an interface called `String`. – crashmstr Aug 01 '17 at 12:45
  • @crashmstr I dont need the extends here since I am implementing a new method in the existing typescript String interface and going to use it globally. – FAISAL Aug 01 '17 at 13:18

3 Answers3

9

I was able to fix this problem. Here is an update on how to solve this issue:


1. Create a file global.d.ts and add the interface extension definitions there.

export { };
declare global
{
    interface String
    {
        /**
         * Translates the given string according to the culture provided.
         * @param cultureName The culture name of the translation target.
         * @returns The translated string.
         */
        translate(cultureName: string): string;
    }
}

2. Create another file with the interface extension methods definition. In my case I named it string.extensions.ts

/**
 * Translates the given string according to the culture provided.
 * @param cultureName The culture name of the translation target.
 * @returns The translated string.
 */    
String.prototype.translate = function(cultureName: string): string
{
    const inputValue = this;

    // Do the translation here
    const translatedValue = 'Willkommen bei meiner App'; // Only for example

    return translatedValue ;
};

3. In your app boot file, in my case its main.ts, add a reference to the global.d.ts and the file containing your extension methods definitions.

/// <reference path="app/core/extensions/global.d.ts" />
//...
import './app/core/extensions/string.extensions';

You just need to import this file once in your project (main.ts) and then you can use it anywhere in the code.

4. Example use in my AppComponent

import {Component} from '@angular/core';    

@Component({
    selector: 'my-app',
    template: `
        Original Value: <h3>{{ originalValue }}</h3>
        Translated Value: <h3>{{ translatedValue }}</h3> 
    `
})
export class AppComponent {

    private originalValue:string;
    private translatedValue:string;

    constructor() {          
        this.originalValue = 'Welcome to my App';
        this.translatedValue = 'Welcome to my App'.translate('de-DE'); 
    }      
}

That's all you need to do to solve this annoying problem.

Here is a link to working plunker: Plunker Demo

FAISAL
  • 33,618
  • 10
  • 97
  • 105
1

This works for me:

Declare an interface

interface String {
    translate():string
}

Usage

String.prototype.translate = function(){
     return "boink"
}

let str : string = "test";
let a : string = str.translate();
console.log(a);   // logs "boink"
Kokodoko
  • 26,167
  • 33
  • 120
  • 197
1

I guess that your declaration is in a separated files. It still uses the base declaration. It is not reachable to the code. Try use the direct import from the file or this one.

///<reference path="test.d.ts"/>
Victor Shelepen
  • 1,966
  • 2
  • 16
  • 41
  • Yes, my declaration is in a separate file. I have included the reference path but that didn't help. – FAISAL Aug 01 '17 at 13:34
  • 1
    Why do not you use pipes for this business case? | translate ? – Victor Shelepen Aug 01 '17 at 15:02
  • I have added the pipe already. I also want to call the pipe transform inside my translate function, as a new String extension function "translate". I dont want to import my TranslationService everywhere in the code. – FAISAL Aug 01 '17 at 15:04
  • You have published the plunk. But It does not disclose the typescript behavior. I guess you simply did not defined the method properly. This is JavaScript error - "TypeError: "Translate this string".translate is not a function" So this method has not been attached yet before you call it. – Victor Shelepen Aug 01 '17 at 15:10