Typescript dynamic properties and methods

I am trying to learn more about typescript.

in javascript you can write a function that returns an object with properties and methods added dynamically.

For example (example only):

function fn(val) {
    var ret = {};

    if (val == 1) {
        ret.prop1 = "stackoverflow";
        ret.fn1 = function () {
            alert("hello stackoverflow");
        }
    }

    if (val == 2) {
        ret.fn2 = function () {
            alert("val=2");
        }
    }

    return ret;

      

}

window.onload = function () {

    alert(fn(1).prop1); //alert "stackoverflow"
    fn(1).fn1(); //alert "hello stackoverflow"

    fn(2).fn2(); //alert "val=2"

      

}

In visual studio intellisense recognizes the return value of a function and allows parameters and functions to be used.

enter image description here

enter image description here

The first image has "prop1" and "fn1 ()", not "fn2 ()"

The second image contains "fn2 ()", not "prop1" and "fn1 ()".

can you do something like this with typescript? How?

The idea is to have one or more functions returning objects with properties and methods added dynamically based on the parameters passed to the function and visible from the intellisense visual studio.

thank

Luke

0


source to share


2 answers


TypeScript interfaces can have optional elements. eg:

interface Foo{
    prop1?:string;
    fn1?:Function;
    fn2?:Function;
}
function fn(val):Foo {
    var ret:Foo = {};

    if (val == 1) {
        ret.prop1 = "stackoverflow";
        ret.fn1 = function () {
            alert("hello stackoverflow");
        }
    }

    if (val == 2) {
        ret.fn2 = function () {
            alert("val=2");
        }
    }

    return ret;
}

      



You don't need to create an explicit interface. You can do it inline:

function fn(val) {
    var ret:{
        prop1?:string;
        fn1?:Function;
        fn2?:Function;
    }= {};

    if (val == 1) {
        ret.prop1 = "stackoverflow";
        ret.fn1 = function () {
            alert("hello stackoverflow");
        }
    }

    if (val == 2) {
        ret.fn2 = function () {
            alert("val=2");
        }
    }

    return ret;
}

      

0


source


Constant overloading (scroll down here) is for this use case, but in my testing I could only get it to work from a string, not a number.

Below is an option (using strings) in your example:



interface Type1 {
  fn1(): void;
  prop1: string;
}

interface Type2 {
  fn2(): void;
}

function fn(val: string): Object;
function fn(val: "1"): Type1;
function fn(val: "2"): Type2;
function fn(val: string): Object {
  var ret: any = {};
  if (val == "1") {
    ret.prop1 = "stackoverflow";
    ret.fn1 = function () {
      alert("hello stackoverflow");
    }
  }
  if (val == "2") {
    ret.fn2 = function () {
      alert("val=2");
    }
  }
  return ret;
}

console.log(fn("1").fn1);
console.log(fn("1").prop1);
console.log(fn("2").fn2);
// Bad: console.log(fn("2").fn1);
// Error: The property 'fn1' does not exist on value of type 'Type2'.

      

On a quick search, I couldn't find any discussion of numbers for this function. Strings are probably the most common use case, but sometimes I could see numbers come in handy. If I was awesome, I would raise the issue here .

0


source







All Articles