Build a function object with properties in TypeScript

后端 未结 9 1262
南旧
南旧 2020-11-28 06:00

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;
         


        
相关标签:
9条回答
  • 2020-11-28 06:37

    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.

    0 讨论(0)
  • 2020-11-28 06:45

    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

    0 讨论(0)
  • 2020-11-28 06:49

    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.

    0 讨论(0)
提交回复
热议问题