Typescript dynamic properties and methods

痴心易碎 提交于 2019-12-11 06:19:36

问题


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.

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


回答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;
}



回答2:


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.



来源:https://stackoverflow.com/questions/19242034/typescript-dynamic-properties-and-methods

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!