1

I'm 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 (just an example):

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 the visual studio the intellisense recognize the return value of the function and allows you to use parameters and functions.

enter image description here

enter image description here

In the first image there are "prop1" and "fn1 ()" and not "fn2 ()"

In the second image there is "fn2 ()" and not "prop1" and "fn1 ()".

you can do something similar with typescript? How?

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

thanks

Luca

2 Answers 2

1

TypeScript interfaces can have optional members. e.g. :

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;
}
Sign up to request clarification or add additional context in comments.

5 Comments

thanks for the reply. If I write: fn (1) the visual studio intellisense does not appear Becomes uncomfortable to use the "fn" Luca
Try saving the result of fn(1) to a variable and see if intellisense comes back alive.
Thanks Alex. It's correct. If i call fn with 1 like parameter i see all property and all methods (prop1, fn1 and fn2) It's possible have a function that return an object that has properties and methods added dynamically at runtime instead of an interface with all properties and methods?
@basarat Basarat Thanks for the example. Even in this example, we need to define an object with all possible properties and methods even if they are not used. If I call fn(1) see also "fn2". In javascript can be added at runtime. The question is: is it possible, as in javascript, add properties or methods at runtime without using interfaces and without having to declare all the properties / methods in an object even if it will be used? See only "prop1" and "fn1" if I call fn (1) and see only "fn2" if I call fn (2)? Thank you. Luca (sorry for English)
@LucaDev, your concern about seeing only the right members is the issue I addressed in my answer. (Sadly, it only supports string parameters.)
0

Overload on constants (scroll down here) is designed for this use case, but in my testing, I could only get it to work with strings and not with numbers.

The following is a variation (using strings) on 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'.

In a quick search, I couldn't find any discussion of numbers for this feature. Strings probably are the more common use case, but I could see numbers coming in handy sometimes. If I were awesome, I'd raise an issue here.

2 Comments

Thanks Tom for the reply.Your example is similar to the example of basarat and is based on interfaces,but only works with parameters of type String.Not being able to write a function that returns an object with properties and methods added at runtime as Javascript (without interface)and use the return value is a limitation."Starts from JavaScript,Ends with JavaScript",but it not does what it does javascript.I'm not an expert on JavaScript or typescript so my opinion is modest and humble.I hope you will correct me and tell me what I did wrong.Thanks and sorry for "bad english".Luca
This isn't the same as basarat's example. Note the different return types for different argument values. Sadly, yes, this is just for strings.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.