Build a function object with properties in TypeScript





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







59















I want to create a function object, which also has some properties held on it. For example in JavaScript I would do:



var f = function() { }
f.someValue = 3;


Now in TypeScript I can describe the type of this as:



var f: { (): any; someValue: number; };


However I can't actually build it, without requiring a cast. Such as:



var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;


How would you build this without a cast?










share|improve this question




















  • 2





    This isn't a direct answer to your question, but for anyone who wants to concisely build a function object with properties, and is OK with casting, the Object-Spread operator seems to do the trick: var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };.

    – Jonathan
    Nov 29 '17 at 19:21




















59















I want to create a function object, which also has some properties held on it. For example in JavaScript I would do:



var f = function() { }
f.someValue = 3;


Now in TypeScript I can describe the type of this as:



var f: { (): any; someValue: number; };


However I can't actually build it, without requiring a cast. Such as:



var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;


How would you build this without a cast?










share|improve this question




















  • 2





    This isn't a direct answer to your question, but for anyone who wants to concisely build a function object with properties, and is OK with casting, the Object-Spread operator seems to do the trick: var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };.

    – Jonathan
    Nov 29 '17 at 19:21
















59












59








59


10






I want to create a function object, which also has some properties held on it. For example in JavaScript I would do:



var f = function() { }
f.someValue = 3;


Now in TypeScript I can describe the type of this as:



var f: { (): any; someValue: number; };


However I can't actually build it, without requiring a cast. Such as:



var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;


How would you build this without a cast?










share|improve this question
















I want to create a function object, which also has some properties held on it. For example in JavaScript I would do:



var f = function() { }
f.someValue = 3;


Now in TypeScript I can describe the type of this as:



var f: { (): any; someValue: number; };


However I can't actually build it, without requiring a cast. Such as:



var f: { (): any; someValue: number; } =
<{ (): any; someValue: number; }>(
function() { }
);
f.someValue = 3;


How would you build this without a cast?







casting typescript function-object






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 29 '17 at 19:24









Jonathan

15.3k34111184




15.3k34111184










asked Oct 7 '12 at 6:08









JL235JL235

1,26911114




1,26911114








  • 2





    This isn't a direct answer to your question, but for anyone who wants to concisely build a function object with properties, and is OK with casting, the Object-Spread operator seems to do the trick: var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };.

    – Jonathan
    Nov 29 '17 at 19:21
















  • 2





    This isn't a direct answer to your question, but for anyone who wants to concisely build a function object with properties, and is OK with casting, the Object-Spread operator seems to do the trick: var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };.

    – Jonathan
    Nov 29 '17 at 19:21










2




2





This isn't a direct answer to your question, but for anyone who wants to concisely build a function object with properties, and is OK with casting, the Object-Spread operator seems to do the trick: var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };.

– Jonathan
Nov 29 '17 at 19:21







This isn't a direct answer to your question, but for anyone who wants to concisely build a function object with properties, and is OK with casting, the Object-Spread operator seems to do the trick: var f: { (): any; someValue: number; } = <{ (): any; someValue: number; }>{ ...(() => "Hello"), someValue: 3 };.

– Jonathan
Nov 29 '17 at 19:21














9 Answers
9






active

oldest

votes


















18














So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:



var f: { (): any; someValue: number; };

f = (() => {
var _f : any = function () { };
_f.someValue = 3;
return _f;
})();


Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.



EDIT: Simplified the code a bit.






share|improve this answer





















  • 5





    As far as I can understand this won't actually check type, so .someValue could be essentially anything.

    – shabunc
    Jan 26 '15 at 0:43











  • The better / updated answer as of 2017/2018 for TypeScript 2.0 is posted by Meirion Hughes below: stackoverflow.com/questions/12766528/… .

    – user3773048
    Jun 7 '18 at 21:19



















90














Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).



The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.



interface F { (): any; someValue: number; }

var f = <F>function () { }
f.someValue = 3

// type error
f.notDeclard = 3





share|improve this answer





















  • 3





    this is awesome, thx

    – peter
    Apr 17 '15 at 15:36






  • 1





    Also is easier to read

    – Sandy Gifford
    Jan 5 '16 at 15:14






  • 1





    I don't understand why the var f line does not cause an error, since at that time there is no someValue property.

    – user663031
    Jul 14 '16 at 16:39






  • 2





    @torazaburo its because it does not check when you cast. To type check you need to do: var f:F = function(){} which will fail in the above example. This answer isn't great for more complicated situations as you lose type checking at the assignment stage.

    – Meirion Hughes
    Jan 26 '17 at 9:16








  • 1





    right but how do you do this with a function declaration instead of a function expression?

    – Alexander Mills
    Apr 2 '17 at 20:27



















49














This is easily achievable now (typescript 2.x) with Object.assign(target, source)



example:



enter image description here



The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.



Enforcing that this resolves to a known interface is also straight-forward. For example:



interface Foo {
(a: number, b: string): string;
foo: string;
}

let method: Foo = Object.assign(
(a: number, b: string) => { return a * a; },
{ foo: 10 }
);


which errors due to incompatible typing:




Error: foo:number not assignable to foo:string

Error: number not assignable to string (return type)




caveat: you may need to polyfill Object.assign if targeting older browsers.






share|improve this answer





















  • 1





    Fantastic, thank you. As of Feb 2017, this is the best answer (for Typescript 2.x users).

    – Andrew Faulkner
    Feb 22 '17 at 12:41











  • Need this to be the accepted answer

    – Patrick Michaelsen
    Oct 25 '18 at 3:29



















41














TypeScript is designed to handle this case through declaration merging:




you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.




Declaration merging lets us say that something is both a function and a namespace (internal module):



function f() { }
namespace f {
export var someValue = 3;
}


This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:



declare function f(): void;
declare namespace f {
export var someValue: number;
}


Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.






share|improve this answer


























  • Upvote for mentioning ambient modules in the answer. This is very typical case when converting or annotating existing JS modules. Exactly what I am looking for!

    – Nipheris
    May 16 '16 at 19:01











  • Lovely. If you want to use this with ES6 modules, you can just do function hello() { .. } namespace hello { export const value = 5; } export default hello; IMO this is much cleaner than Object.assign or similar runtime hacks. No runtime, no type assertions, no nothing.

    – skrebbel
    Jul 26 '17 at 19:26













  • This answer is great, but how do you attach a Symbol such as Symbol.iterator to a function?

    – kzh
    Jul 28 '17 at 4:20











  • Link above doesn't work any more, correct would be typescriptlang.org/docs/handbook/declaration-merging.html

    – iJungleBoy
    Sep 5 '17 at 20:56











  • @iJungleBoy thanks, updated

    – mk.
    Sep 6 '17 at 16:44



















2














As a shortcut, you can dynamically assign the object value using the ['property'] accessor:



var f = function() { }
f['someValue'] = 3;


This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:



var val = f.someValue; // This won't work
var val = f['someValue']; // Yeah, I meant to do that


However, if you really want the type checking for the property value, this won't work.






share|improve this answer































    1














    An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.



    Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:



    function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
    Object.keys(from).forEach(key => onto[key] = from[key]);
    return onto as T1 & T2;
    }


    This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:



    interface Foo {
    (message: string): void;
    bar(count: number): void;
    }

    const foo: Foo = merge(
    (message: string) => console.log(`message is ${message}`), {
    bar(count: number) {
    console.log(`bar was passed ${count}`)
    }
    }
    );


    Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.



    NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:



    function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
    if (typeof from !== "object" || from instanceof Array) {
    throw new Error("merge: 'from' must be an ordinary object");
    }
    Object.keys(from).forEach(key => onto[key] = from[key]);
    return onto as T1 & T2;
    }





    share|improve this answer































      1














      I can't say that it's very straightforward but it's definitely possible:



      interface Optional {
      <T>(value?: T): OptionalMonad<T>;
      empty(): OptionalMonad<any>;
      }

      const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
      Optional.empty = () => OptionalCreator();


      if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional






      share|improve this answer

































        0














        This departs from strong typing, but you can do



        var f: any = function() { }
        f.someValue = 3;


        if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.



        "You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)






        share|improve this answer































          0














          Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:



          function f () {}
          f.someValue = 3; // fine
          const g = function () {};
          g.someValue = 3; // also fine
          var h = function () {};
          h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"


          Reference and online example.






          share|improve this answer
























            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12766528%2fbuild-a-function-object-with-properties-in-typescript%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            9 Answers
            9






            active

            oldest

            votes








            9 Answers
            9






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            18














            So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:



            var f: { (): any; someValue: number; };

            f = (() => {
            var _f : any = function () { };
            _f.someValue = 3;
            return _f;
            })();


            Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.



            EDIT: Simplified the code a bit.






            share|improve this answer





















            • 5





              As far as I can understand this won't actually check type, so .someValue could be essentially anything.

              – shabunc
              Jan 26 '15 at 0:43











            • The better / updated answer as of 2017/2018 for TypeScript 2.0 is posted by Meirion Hughes below: stackoverflow.com/questions/12766528/… .

              – user3773048
              Jun 7 '18 at 21:19
















            18














            So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:



            var f: { (): any; someValue: number; };

            f = (() => {
            var _f : any = function () { };
            _f.someValue = 3;
            return _f;
            })();


            Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.



            EDIT: Simplified the code a bit.






            share|improve this answer





















            • 5





              As far as I can understand this won't actually check type, so .someValue could be essentially anything.

              – shabunc
              Jan 26 '15 at 0:43











            • The better / updated answer as of 2017/2018 for TypeScript 2.0 is posted by Meirion Hughes below: stackoverflow.com/questions/12766528/… .

              – user3773048
              Jun 7 '18 at 21:19














            18












            18








            18







            So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:



            var f: { (): any; someValue: number; };

            f = (() => {
            var _f : any = function () { };
            _f.someValue = 3;
            return _f;
            })();


            Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.



            EDIT: Simplified the code a bit.






            share|improve this answer















            So if the requirement is to simply build and assign that function to "f" without a cast, here is a possible solution:



            var f: { (): any; someValue: number; };

            f = (() => {
            var _f : any = function () { };
            _f.someValue = 3;
            return _f;
            })();


            Essentially, it uses a self executing function literal to "construct" an object that will match that signature before the assignment is done. The only weirdness is that the inner declaration of the function needs to be of type 'any', otherwise the compiler cries that you're assigning to a property which does not exist on the object yet.



            EDIT: Simplified the code a bit.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Oct 7 '12 at 17:05

























            answered Oct 7 '12 at 16:33









            nxnnxn

            2,16911415




            2,16911415








            • 5





              As far as I can understand this won't actually check type, so .someValue could be essentially anything.

              – shabunc
              Jan 26 '15 at 0:43











            • The better / updated answer as of 2017/2018 for TypeScript 2.0 is posted by Meirion Hughes below: stackoverflow.com/questions/12766528/… .

              – user3773048
              Jun 7 '18 at 21:19














            • 5





              As far as I can understand this won't actually check type, so .someValue could be essentially anything.

              – shabunc
              Jan 26 '15 at 0:43











            • The better / updated answer as of 2017/2018 for TypeScript 2.0 is posted by Meirion Hughes below: stackoverflow.com/questions/12766528/… .

              – user3773048
              Jun 7 '18 at 21:19








            5




            5





            As far as I can understand this won't actually check type, so .someValue could be essentially anything.

            – shabunc
            Jan 26 '15 at 0:43





            As far as I can understand this won't actually check type, so .someValue could be essentially anything.

            – shabunc
            Jan 26 '15 at 0:43













            The better / updated answer as of 2017/2018 for TypeScript 2.0 is posted by Meirion Hughes below: stackoverflow.com/questions/12766528/… .

            – user3773048
            Jun 7 '18 at 21:19





            The better / updated answer as of 2017/2018 for TypeScript 2.0 is posted by Meirion Hughes below: stackoverflow.com/questions/12766528/… .

            – user3773048
            Jun 7 '18 at 21:19













            90














            Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).



            The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.



            interface F { (): any; someValue: number; }

            var f = <F>function () { }
            f.someValue = 3

            // type error
            f.notDeclard = 3





            share|improve this answer





















            • 3





              this is awesome, thx

              – peter
              Apr 17 '15 at 15:36






            • 1





              Also is easier to read

              – Sandy Gifford
              Jan 5 '16 at 15:14






            • 1





              I don't understand why the var f line does not cause an error, since at that time there is no someValue property.

              – user663031
              Jul 14 '16 at 16:39






            • 2





              @torazaburo its because it does not check when you cast. To type check you need to do: var f:F = function(){} which will fail in the above example. This answer isn't great for more complicated situations as you lose type checking at the assignment stage.

              – Meirion Hughes
              Jan 26 '17 at 9:16








            • 1





              right but how do you do this with a function declaration instead of a function expression?

              – Alexander Mills
              Apr 2 '17 at 20:27
















            90














            Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).



            The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.



            interface F { (): any; someValue: number; }

            var f = <F>function () { }
            f.someValue = 3

            // type error
            f.notDeclard = 3





            share|improve this answer





















            • 3





              this is awesome, thx

              – peter
              Apr 17 '15 at 15:36






            • 1





              Also is easier to read

              – Sandy Gifford
              Jan 5 '16 at 15:14






            • 1





              I don't understand why the var f line does not cause an error, since at that time there is no someValue property.

              – user663031
              Jul 14 '16 at 16:39






            • 2





              @torazaburo its because it does not check when you cast. To type check you need to do: var f:F = function(){} which will fail in the above example. This answer isn't great for more complicated situations as you lose type checking at the assignment stage.

              – Meirion Hughes
              Jan 26 '17 at 9:16








            • 1





              right but how do you do this with a function declaration instead of a function expression?

              – Alexander Mills
              Apr 2 '17 at 20:27














            90












            90








            90







            Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).



            The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.



            interface F { (): any; someValue: number; }

            var f = <F>function () { }
            f.someValue = 3

            // type error
            f.notDeclard = 3





            share|improve this answer















            Update: This answer was the best solution in earlier versions of TypeScript, but there are better options available in newer versions (see other answers).



            The accepted answer works and might be required in some situations, but have the downside of providing no type safety for building up the object. This technique will at least throw a type error if you attempt to add an undefined property.



            interface F { (): any; someValue: number; }

            var f = <F>function () { }
            f.someValue = 3

            // type error
            f.notDeclard = 3






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Dec 28 '17 at 20:20

























            answered Sep 5 '13 at 15:12









            Greg WeberGreg Weber

            2,20921519




            2,20921519








            • 3





              this is awesome, thx

              – peter
              Apr 17 '15 at 15:36






            • 1





              Also is easier to read

              – Sandy Gifford
              Jan 5 '16 at 15:14






            • 1





              I don't understand why the var f line does not cause an error, since at that time there is no someValue property.

              – user663031
              Jul 14 '16 at 16:39






            • 2





              @torazaburo its because it does not check when you cast. To type check you need to do: var f:F = function(){} which will fail in the above example. This answer isn't great for more complicated situations as you lose type checking at the assignment stage.

              – Meirion Hughes
              Jan 26 '17 at 9:16








            • 1





              right but how do you do this with a function declaration instead of a function expression?

              – Alexander Mills
              Apr 2 '17 at 20:27














            • 3





              this is awesome, thx

              – peter
              Apr 17 '15 at 15:36






            • 1





              Also is easier to read

              – Sandy Gifford
              Jan 5 '16 at 15:14






            • 1





              I don't understand why the var f line does not cause an error, since at that time there is no someValue property.

              – user663031
              Jul 14 '16 at 16:39






            • 2





              @torazaburo its because it does not check when you cast. To type check you need to do: var f:F = function(){} which will fail in the above example. This answer isn't great for more complicated situations as you lose type checking at the assignment stage.

              – Meirion Hughes
              Jan 26 '17 at 9:16








            • 1





              right but how do you do this with a function declaration instead of a function expression?

              – Alexander Mills
              Apr 2 '17 at 20:27








            3




            3





            this is awesome, thx

            – peter
            Apr 17 '15 at 15:36





            this is awesome, thx

            – peter
            Apr 17 '15 at 15:36




            1




            1





            Also is easier to read

            – Sandy Gifford
            Jan 5 '16 at 15:14





            Also is easier to read

            – Sandy Gifford
            Jan 5 '16 at 15:14




            1




            1





            I don't understand why the var f line does not cause an error, since at that time there is no someValue property.

            – user663031
            Jul 14 '16 at 16:39





            I don't understand why the var f line does not cause an error, since at that time there is no someValue property.

            – user663031
            Jul 14 '16 at 16:39




            2




            2





            @torazaburo its because it does not check when you cast. To type check you need to do: var f:F = function(){} which will fail in the above example. This answer isn't great for more complicated situations as you lose type checking at the assignment stage.

            – Meirion Hughes
            Jan 26 '17 at 9:16







            @torazaburo its because it does not check when you cast. To type check you need to do: var f:F = function(){} which will fail in the above example. This answer isn't great for more complicated situations as you lose type checking at the assignment stage.

            – Meirion Hughes
            Jan 26 '17 at 9:16






            1




            1





            right but how do you do this with a function declaration instead of a function expression?

            – Alexander Mills
            Apr 2 '17 at 20:27





            right but how do you do this with a function declaration instead of a function expression?

            – Alexander Mills
            Apr 2 '17 at 20:27











            49














            This is easily achievable now (typescript 2.x) with Object.assign(target, source)



            example:



            enter image description here



            The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.



            Enforcing that this resolves to a known interface is also straight-forward. For example:



            interface Foo {
            (a: number, b: string): string;
            foo: string;
            }

            let method: Foo = Object.assign(
            (a: number, b: string) => { return a * a; },
            { foo: 10 }
            );


            which errors due to incompatible typing:




            Error: foo:number not assignable to foo:string

            Error: number not assignable to string (return type)




            caveat: you may need to polyfill Object.assign if targeting older browsers.






            share|improve this answer





















            • 1





              Fantastic, thank you. As of Feb 2017, this is the best answer (for Typescript 2.x users).

              – Andrew Faulkner
              Feb 22 '17 at 12:41











            • Need this to be the accepted answer

              – Patrick Michaelsen
              Oct 25 '18 at 3:29
















            49














            This is easily achievable now (typescript 2.x) with Object.assign(target, source)



            example:



            enter image description here



            The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.



            Enforcing that this resolves to a known interface is also straight-forward. For example:



            interface Foo {
            (a: number, b: string): string;
            foo: string;
            }

            let method: Foo = Object.assign(
            (a: number, b: string) => { return a * a; },
            { foo: 10 }
            );


            which errors due to incompatible typing:




            Error: foo:number not assignable to foo:string

            Error: number not assignable to string (return type)




            caveat: you may need to polyfill Object.assign if targeting older browsers.






            share|improve this answer





















            • 1





              Fantastic, thank you. As of Feb 2017, this is the best answer (for Typescript 2.x users).

              – Andrew Faulkner
              Feb 22 '17 at 12:41











            • Need this to be the accepted answer

              – Patrick Michaelsen
              Oct 25 '18 at 3:29














            49












            49








            49







            This is easily achievable now (typescript 2.x) with Object.assign(target, source)



            example:



            enter image description here



            The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.



            Enforcing that this resolves to a known interface is also straight-forward. For example:



            interface Foo {
            (a: number, b: string): string;
            foo: string;
            }

            let method: Foo = Object.assign(
            (a: number, b: string) => { return a * a; },
            { foo: 10 }
            );


            which errors due to incompatible typing:




            Error: foo:number not assignable to foo:string

            Error: number not assignable to string (return type)




            caveat: you may need to polyfill Object.assign if targeting older browsers.






            share|improve this answer















            This is easily achievable now (typescript 2.x) with Object.assign(target, source)



            example:



            enter image description here



            The magic here is that Object.assign<T, U>(t: T, u: U) is typed to return the intersection T & U.



            Enforcing that this resolves to a known interface is also straight-forward. For example:



            interface Foo {
            (a: number, b: string): string;
            foo: string;
            }

            let method: Foo = Object.assign(
            (a: number, b: string) => { return a * a; },
            { foo: 10 }
            );


            which errors due to incompatible typing:




            Error: foo:number not assignable to foo:string

            Error: number not assignable to string (return type)




            caveat: you may need to polyfill Object.assign if targeting older browsers.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Oct 25 '18 at 7:57

























            answered Jan 25 '17 at 13:43









            Meirion HughesMeirion Hughes

            12.9k54690




            12.9k54690








            • 1





              Fantastic, thank you. As of Feb 2017, this is the best answer (for Typescript 2.x users).

              – Andrew Faulkner
              Feb 22 '17 at 12:41











            • Need this to be the accepted answer

              – Patrick Michaelsen
              Oct 25 '18 at 3:29














            • 1





              Fantastic, thank you. As of Feb 2017, this is the best answer (for Typescript 2.x users).

              – Andrew Faulkner
              Feb 22 '17 at 12:41











            • Need this to be the accepted answer

              – Patrick Michaelsen
              Oct 25 '18 at 3:29








            1




            1





            Fantastic, thank you. As of Feb 2017, this is the best answer (for Typescript 2.x users).

            – Andrew Faulkner
            Feb 22 '17 at 12:41





            Fantastic, thank you. As of Feb 2017, this is the best answer (for Typescript 2.x users).

            – Andrew Faulkner
            Feb 22 '17 at 12:41













            Need this to be the accepted answer

            – Patrick Michaelsen
            Oct 25 '18 at 3:29





            Need this to be the accepted answer

            – Patrick Michaelsen
            Oct 25 '18 at 3:29











            41














            TypeScript is designed to handle this case through declaration merging:




            you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.




            Declaration merging lets us say that something is both a function and a namespace (internal module):



            function f() { }
            namespace f {
            export var someValue = 3;
            }


            This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:



            declare function f(): void;
            declare namespace f {
            export var someValue: number;
            }


            Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.






            share|improve this answer


























            • Upvote for mentioning ambient modules in the answer. This is very typical case when converting or annotating existing JS modules. Exactly what I am looking for!

              – Nipheris
              May 16 '16 at 19:01











            • Lovely. If you want to use this with ES6 modules, you can just do function hello() { .. } namespace hello { export const value = 5; } export default hello; IMO this is much cleaner than Object.assign or similar runtime hacks. No runtime, no type assertions, no nothing.

              – skrebbel
              Jul 26 '17 at 19:26













            • This answer is great, but how do you attach a Symbol such as Symbol.iterator to a function?

              – kzh
              Jul 28 '17 at 4:20











            • Link above doesn't work any more, correct would be typescriptlang.org/docs/handbook/declaration-merging.html

              – iJungleBoy
              Sep 5 '17 at 20:56











            • @iJungleBoy thanks, updated

              – mk.
              Sep 6 '17 at 16:44
















            41














            TypeScript is designed to handle this case through declaration merging:




            you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.




            Declaration merging lets us say that something is both a function and a namespace (internal module):



            function f() { }
            namespace f {
            export var someValue = 3;
            }


            This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:



            declare function f(): void;
            declare namespace f {
            export var someValue: number;
            }


            Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.






            share|improve this answer


























            • Upvote for mentioning ambient modules in the answer. This is very typical case when converting or annotating existing JS modules. Exactly what I am looking for!

              – Nipheris
              May 16 '16 at 19:01











            • Lovely. If you want to use this with ES6 modules, you can just do function hello() { .. } namespace hello { export const value = 5; } export default hello; IMO this is much cleaner than Object.assign or similar runtime hacks. No runtime, no type assertions, no nothing.

              – skrebbel
              Jul 26 '17 at 19:26













            • This answer is great, but how do you attach a Symbol such as Symbol.iterator to a function?

              – kzh
              Jul 28 '17 at 4:20











            • Link above doesn't work any more, correct would be typescriptlang.org/docs/handbook/declaration-merging.html

              – iJungleBoy
              Sep 5 '17 at 20:56











            • @iJungleBoy thanks, updated

              – mk.
              Sep 6 '17 at 16:44














            41












            41








            41







            TypeScript is designed to handle this case through declaration merging:




            you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.




            Declaration merging lets us say that something is both a function and a namespace (internal module):



            function f() { }
            namespace f {
            export var someValue = 3;
            }


            This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:



            declare function f(): void;
            declare namespace f {
            export var someValue: number;
            }


            Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.






            share|improve this answer















            TypeScript is designed to handle this case through declaration merging:




            you may also be familiar with JavaScript practice of creating a function and then extending the function further by adding properties onto the function. TypeScript uses declaration merging to build up definitions like this in a type-safe way.




            Declaration merging lets us say that something is both a function and a namespace (internal module):



            function f() { }
            namespace f {
            export var someValue = 3;
            }


            This preserves typing and lets us write both f() and f.someValue. When writing a .d.ts file for existing JavaScript code, use declare:



            declare function f(): void;
            declare namespace f {
            export var someValue: number;
            }


            Adding properties to functions is often a confusing or unexpected pattern in TypeScript, so try to avoid it, but it can be necessary when using or converting older JS code. This is one of the only times it would be appropriate to mix internal modules (namespaces) with external.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 6 '17 at 16:42

























            answered Oct 28 '15 at 13:47









            mk.mk.

            6,93043251




            6,93043251













            • Upvote for mentioning ambient modules in the answer. This is very typical case when converting or annotating existing JS modules. Exactly what I am looking for!

              – Nipheris
              May 16 '16 at 19:01











            • Lovely. If you want to use this with ES6 modules, you can just do function hello() { .. } namespace hello { export const value = 5; } export default hello; IMO this is much cleaner than Object.assign or similar runtime hacks. No runtime, no type assertions, no nothing.

              – skrebbel
              Jul 26 '17 at 19:26













            • This answer is great, but how do you attach a Symbol such as Symbol.iterator to a function?

              – kzh
              Jul 28 '17 at 4:20











            • Link above doesn't work any more, correct would be typescriptlang.org/docs/handbook/declaration-merging.html

              – iJungleBoy
              Sep 5 '17 at 20:56











            • @iJungleBoy thanks, updated

              – mk.
              Sep 6 '17 at 16:44



















            • Upvote for mentioning ambient modules in the answer. This is very typical case when converting or annotating existing JS modules. Exactly what I am looking for!

              – Nipheris
              May 16 '16 at 19:01











            • Lovely. If you want to use this with ES6 modules, you can just do function hello() { .. } namespace hello { export const value = 5; } export default hello; IMO this is much cleaner than Object.assign or similar runtime hacks. No runtime, no type assertions, no nothing.

              – skrebbel
              Jul 26 '17 at 19:26













            • This answer is great, but how do you attach a Symbol such as Symbol.iterator to a function?

              – kzh
              Jul 28 '17 at 4:20











            • Link above doesn't work any more, correct would be typescriptlang.org/docs/handbook/declaration-merging.html

              – iJungleBoy
              Sep 5 '17 at 20:56











            • @iJungleBoy thanks, updated

              – mk.
              Sep 6 '17 at 16:44

















            Upvote for mentioning ambient modules in the answer. This is very typical case when converting or annotating existing JS modules. Exactly what I am looking for!

            – Nipheris
            May 16 '16 at 19:01





            Upvote for mentioning ambient modules in the answer. This is very typical case when converting or annotating existing JS modules. Exactly what I am looking for!

            – Nipheris
            May 16 '16 at 19:01













            Lovely. If you want to use this with ES6 modules, you can just do function hello() { .. } namespace hello { export const value = 5; } export default hello; IMO this is much cleaner than Object.assign or similar runtime hacks. No runtime, no type assertions, no nothing.

            – skrebbel
            Jul 26 '17 at 19:26







            Lovely. If you want to use this with ES6 modules, you can just do function hello() { .. } namespace hello { export const value = 5; } export default hello; IMO this is much cleaner than Object.assign or similar runtime hacks. No runtime, no type assertions, no nothing.

            – skrebbel
            Jul 26 '17 at 19:26















            This answer is great, but how do you attach a Symbol such as Symbol.iterator to a function?

            – kzh
            Jul 28 '17 at 4:20





            This answer is great, but how do you attach a Symbol such as Symbol.iterator to a function?

            – kzh
            Jul 28 '17 at 4:20













            Link above doesn't work any more, correct would be typescriptlang.org/docs/handbook/declaration-merging.html

            – iJungleBoy
            Sep 5 '17 at 20:56





            Link above doesn't work any more, correct would be typescriptlang.org/docs/handbook/declaration-merging.html

            – iJungleBoy
            Sep 5 '17 at 20:56













            @iJungleBoy thanks, updated

            – mk.
            Sep 6 '17 at 16:44





            @iJungleBoy thanks, updated

            – mk.
            Sep 6 '17 at 16:44











            2














            As a shortcut, you can dynamically assign the object value using the ['property'] accessor:



            var f = function() { }
            f['someValue'] = 3;


            This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:



            var val = f.someValue; // This won't work
            var val = f['someValue']; // Yeah, I meant to do that


            However, if you really want the type checking for the property value, this won't work.






            share|improve this answer




























              2














              As a shortcut, you can dynamically assign the object value using the ['property'] accessor:



              var f = function() { }
              f['someValue'] = 3;


              This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:



              var val = f.someValue; // This won't work
              var val = f['someValue']; // Yeah, I meant to do that


              However, if you really want the type checking for the property value, this won't work.






              share|improve this answer


























                2












                2








                2







                As a shortcut, you can dynamically assign the object value using the ['property'] accessor:



                var f = function() { }
                f['someValue'] = 3;


                This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:



                var val = f.someValue; // This won't work
                var val = f['someValue']; // Yeah, I meant to do that


                However, if you really want the type checking for the property value, this won't work.






                share|improve this answer













                As a shortcut, you can dynamically assign the object value using the ['property'] accessor:



                var f = function() { }
                f['someValue'] = 3;


                This bypasses the type checking. However, it is pretty safe because you have to intentionally access the property the same way:



                var val = f.someValue; // This won't work
                var val = f['someValue']; // Yeah, I meant to do that


                However, if you really want the type checking for the property value, this won't work.







                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Oct 11 '12 at 4:38









                Rick LoveRick Love

                7,76431823




                7,76431823























                    1














                    An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.



                    Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:



                    function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                    Object.keys(from).forEach(key => onto[key] = from[key]);
                    return onto as T1 & T2;
                    }


                    This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:



                    interface Foo {
                    (message: string): void;
                    bar(count: number): void;
                    }

                    const foo: Foo = merge(
                    (message: string) => console.log(`message is ${message}`), {
                    bar(count: number) {
                    console.log(`bar was passed ${count}`)
                    }
                    }
                    );


                    Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.



                    NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:



                    function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                    if (typeof from !== "object" || from instanceof Array) {
                    throw new Error("merge: 'from' must be an ordinary object");
                    }
                    Object.keys(from).forEach(key => onto[key] = from[key]);
                    return onto as T1 & T2;
                    }





                    share|improve this answer




























                      1














                      An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.



                      Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:



                      function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                      Object.keys(from).forEach(key => onto[key] = from[key]);
                      return onto as T1 & T2;
                      }


                      This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:



                      interface Foo {
                      (message: string): void;
                      bar(count: number): void;
                      }

                      const foo: Foo = merge(
                      (message: string) => console.log(`message is ${message}`), {
                      bar(count: number) {
                      console.log(`bar was passed ${count}`)
                      }
                      }
                      );


                      Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.



                      NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:



                      function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                      if (typeof from !== "object" || from instanceof Array) {
                      throw new Error("merge: 'from' must be an ordinary object");
                      }
                      Object.keys(from).forEach(key => onto[key] = from[key]);
                      return onto as T1 & T2;
                      }





                      share|improve this answer


























                        1












                        1








                        1







                        An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.



                        Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:



                        function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                        Object.keys(from).forEach(key => onto[key] = from[key]);
                        return onto as T1 & T2;
                        }


                        This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:



                        interface Foo {
                        (message: string): void;
                        bar(count: number): void;
                        }

                        const foo: Foo = merge(
                        (message: string) => console.log(`message is ${message}`), {
                        bar(count: number) {
                        console.log(`bar was passed ${count}`)
                        }
                        }
                        );


                        Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.



                        NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:



                        function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                        if (typeof from !== "object" || from instanceof Array) {
                        throw new Error("merge: 'from' must be an ordinary object");
                        }
                        Object.keys(from).forEach(key => onto[key] = from[key]);
                        return onto as T1 & T2;
                        }





                        share|improve this answer













                        An updated answer: since the addition of intersection types via &, it is possible to "merge" two inferred types on the fly.



                        Here's a general helper that reads the properties of some object from and copies them over an object onto. It returns the same object onto but with a new type that includes both sets of properties, so correctly describing the runtime behaviour:



                        function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                        Object.keys(from).forEach(key => onto[key] = from[key]);
                        return onto as T1 & T2;
                        }


                        This low-level helper does still perform a type-assertion, but it is type-safe by design. With this helper in place, we have an operator that we can use to solve the OP's problem with full type safety:



                        interface Foo {
                        (message: string): void;
                        bar(count: number): void;
                        }

                        const foo: Foo = merge(
                        (message: string) => console.log(`message is ${message}`), {
                        bar(count: number) {
                        console.log(`bar was passed ${count}`)
                        }
                        }
                        );


                        Click here to try it out in the TypeScript Playground. Note that we have constrained foo to be of type Foo, so the result of merge has to be a complete Foo. So if you rename bar to bad then you get a type error.



                        NB There is still one type hole here, however. TypeScript doesn't provide a way to constrain a type parameter to be "not a function". So you could get confused and pass your function as the second argument to merge, and that wouldn't work. So until this can be declared, we have to catch it at runtime:



                        function merge<T1, T2>(onto: T1, from: T2): T1 & T2 {
                        if (typeof from !== "object" || from instanceof Array) {
                        throw new Error("merge: 'from' must be an ordinary object");
                        }
                        Object.keys(from).forEach(key => onto[key] = from[key]);
                        return onto as T1 & T2;
                        }






                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Mar 10 '16 at 19:14









                        Daniel EarwickerDaniel Earwicker

                        94.8k31180257




                        94.8k31180257























                            1














                            I can't say that it's very straightforward but it's definitely possible:



                            interface Optional {
                            <T>(value?: T): OptionalMonad<T>;
                            empty(): OptionalMonad<any>;
                            }

                            const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
                            Optional.empty = () => OptionalCreator();


                            if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional






                            share|improve this answer






























                              1














                              I can't say that it's very straightforward but it's definitely possible:



                              interface Optional {
                              <T>(value?: T): OptionalMonad<T>;
                              empty(): OptionalMonad<any>;
                              }

                              const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
                              Optional.empty = () => OptionalCreator();


                              if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional






                              share|improve this answer




























                                1












                                1








                                1







                                I can't say that it's very straightforward but it's definitely possible:



                                interface Optional {
                                <T>(value?: T): OptionalMonad<T>;
                                empty(): OptionalMonad<any>;
                                }

                                const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
                                Optional.empty = () => OptionalCreator();


                                if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional






                                share|improve this answer















                                I can't say that it's very straightforward but it's definitely possible:



                                interface Optional {
                                <T>(value?: T): OptionalMonad<T>;
                                empty(): OptionalMonad<any>;
                                }

                                const Optional = (<T>(value?: T) => OptionalCreator(value)) as Optional;
                                Optional.empty = () => OptionalCreator();


                                if you got curious this is from a gist of mine with the TypeScript/JavaScript version of Optional







                                share|improve this answer














                                share|improve this answer



                                share|improve this answer








                                edited Feb 8 '18 at 0:10

























                                answered Feb 7 '18 at 23:57









                                thiagohthiagoh

                                4,01463664




                                4,01463664























                                    0














                                    This departs from strong typing, but you can do



                                    var f: any = function() { }
                                    f.someValue = 3;


                                    if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.



                                    "You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)






                                    share|improve this answer




























                                      0














                                      This departs from strong typing, but you can do



                                      var f: any = function() { }
                                      f.someValue = 3;


                                      if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.



                                      "You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)






                                      share|improve this answer


























                                        0












                                        0








                                        0







                                        This departs from strong typing, but you can do



                                        var f: any = function() { }
                                        f.someValue = 3;


                                        if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.



                                        "You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)






                                        share|improve this answer













                                        This departs from strong typing, but you can do



                                        var f: any = function() { }
                                        f.someValue = 3;


                                        if you are trying to get around oppressive strong typing like I was when I found this question. Sadly this is a case TypeScript fails on perfectly valid JavaScript so you have to you tell TypeScript to back off.



                                        "You JavaScript is perfectly valid TypeScript" evaluates to false. (Note: using 0.95)







                                        share|improve this answer












                                        share|improve this answer



                                        share|improve this answer










                                        answered Feb 21 '14 at 15:59









                                        WillSeitzWillSeitz

                                        6312




                                        6312























                                            0














                                            Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:



                                            function f () {}
                                            f.someValue = 3; // fine
                                            const g = function () {};
                                            g.someValue = 3; // also fine
                                            var h = function () {};
                                            h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"


                                            Reference and online example.






                                            share|improve this answer




























                                              0














                                              Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:



                                              function f () {}
                                              f.someValue = 3; // fine
                                              const g = function () {};
                                              g.someValue = 3; // also fine
                                              var h = function () {};
                                              h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"


                                              Reference and online example.






                                              share|improve this answer


























                                                0












                                                0








                                                0







                                                Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:



                                                function f () {}
                                                f.someValue = 3; // fine
                                                const g = function () {};
                                                g.someValue = 3; // also fine
                                                var h = function () {};
                                                h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"


                                                Reference and online example.






                                                share|improve this answer













                                                Old question, but for versions of TypeScript starting with 3.1, you can simply do the property assignment as you would in plain JS, as long as you use a function declaration or the const keyword for your variable:



                                                function f () {}
                                                f.someValue = 3; // fine
                                                const g = function () {};
                                                g.someValue = 3; // also fine
                                                var h = function () {};
                                                h.someValue = 3; // Error: "Property 'someValue' does not exist on type '() => void'"


                                                Reference and online example.







                                                share|improve this answer












                                                share|improve this answer



                                                share|improve this answer










                                                answered Nov 26 '18 at 21:38









                                                Geo1088Geo1088

                                                3151514




                                                3151514






























                                                    draft saved

                                                    draft discarded




















































                                                    Thanks for contributing an answer to Stack Overflow!


                                                    • Please be sure to answer the question. Provide details and share your research!

                                                    But avoid



                                                    • Asking for help, clarification, or responding to other answers.

                                                    • Making statements based on opinion; back them up with references or personal experience.


                                                    To learn more, see our tips on writing great answers.




                                                    draft saved


                                                    draft discarded














                                                    StackExchange.ready(
                                                    function () {
                                                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f12766528%2fbuild-a-function-object-with-properties-in-typescript%23new-answer', 'question_page');
                                                    }
                                                    );

                                                    Post as a guest















                                                    Required, but never shown





















































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown

































                                                    Required, but never shown














                                                    Required, but never shown












                                                    Required, but never shown







                                                    Required, but never shown







                                                    Popular posts from this blog

                                                    To store a contact into the json file from server.js file using a class in NodeJS

                                                    Redirect URL with Chrome Remote Debugging Android Devices

                                                    Dieringhausen