How to define global function in TypeScript?

前端 未结 3 1031
心在旅途
心在旅途 2020-12-06 16:22

I want to define a global function that is available everywhere, without the need to import the module when used.

This function aims to replace the safe navigation o

相关标签:
3条回答
  • 2020-12-06 16:30

    Thanks to @Romain Deneau. His answer worked for me. Here is my simplified one to make it look easier to get the point of his answer. (Mine assumes the scripts run on a browser. Also, I omitted signature of function s.)

    Define function outside of any class.

    function s() {
        console.log("invoked s()!");
    }
    
    (window as any).s = s;
    

    Using this global function s from TypeScript class is like below;

    declare var s;
    
    export class MyClass {
        public static callFunctionS() {
            s();
        }
    }
    
    0 讨论(0)
  • 2020-12-06 16:33

    global.ts(x) needs just a little tweak to be a valid "global module" (a module with side effects only): remove the export keyword and add some code to augment the global object. You can also provide the global declaration in the same file and remove global.d.ts.

    function _s<T>(object: T | null, defaultValue: T = {} as T) : T {
        return object == null
            ? defaultValue
            : object as T;
    }
    
    // Global declaration
    declare var s: typeof _s;
    
    // Global scope augmentation
    var window = window || null;
    const _global = (window || global) as any;
    _global.s = _s;
    

    To use it, just import the module once, for instance in App.tsx via a global import: import './global';.

    Tested with mocha, chai, ts-node:

    import { expect } from 'chai';
    import './global'; // To do once at app bootstrapping
    
    describe('global s()', () => {
        it('should replace null with empty object', () => {
            const result = s(null);
            expect(result).to.eql({});
        });
    
        it('should replace undefined with empty object', () => {
            const result = s(undefined);
            expect(result).to.eql({});
        });
    
        it('should replace null with the given default value', () => {
            const defVal = { def: 'val' };
            const result = s(null, defVal);
            expect(result).to.eql({ def: 'val' });
        });
    
        it('should preserve defined object', () => {
            const object = { bar: 'a' };
            const result = s(object);
            expect(result).to.eql(object);
        });
    });
    
    0 讨论(0)
  • 2020-12-06 16:45

    You're defining the type for the compiler, but not actually attaching it to the global namespace — window in the browser, global in node. Instead of exporting it from the module, attach it. For isomorphic use, use something like...

    function s() { ... }
    
    // must cast as any to set property on window
    const _global = (window /* browser */ || global /* node */) as any
    _global.s = s
    

    You can also ditch the .d.ts file and declare the type in the same file using declare global, e.g.

    // we must force tsc to interpret this file as a module, resolves
    // "Augmentations for the global scope can only be directly nested in external modules or ambient module declarations."
    // error
    export {}
    
    declare global {
      function s<T>(someObject: T | null | undefined, defaultValue?: T | null | undefined) : T;
    }
    
    const _global = (window /* browser */ || global /* node */) as any
    _global.s = function<T>(object: T | null | undefined, defaultValue: T | null = null) : T {
      if (typeof object === 'undefined' || object === null)
        return defaultValue as T;
      else
        return object;
    }
    
    0 讨论(0)
提交回复
热议问题