如何在TypeScript中定义全局函数?

six*_*rm1 16 typescript

我想定义一个可在任何地方使用的全局函数,而无需在使用时导入模块.

此功能旨在替换C#中提供的安全导航操作符(?).为了便于阅读,我不想在函数前加上模块名称.

Global.d.ts:

declare function s<T>(someObject: T | null | undefined, defaultValue?: T | null | undefined) : T;
Run Code Online (Sandbox Code Playgroud)

Global.tsx:

///<reference path="Global.d.ts" />

export function s<T>(object: T | null | undefined, defaultValue: T | null = null = {} as T) : T {
    if (typeof object === 'undefined' || object === null)
        return defaultValue as T;
    else
        return object;
}
Run Code Online (Sandbox Code Playgroud)

App.tsx(root TypeScript文件):

import 'Global';
Run Code Online (Sandbox Code Playgroud)

其他TSX文件(方法用法):

s(s(nullableVar).member).member; //Runtime error
Run Code Online (Sandbox Code Playgroud)

这编译很好,但是,在浏览器中抛出' s is not a function'.

cas*_*ebb 18

您正在为编译器定义类型,但实际上并未将其附加到全局命名空间 - window在浏览器中,global在节点中.不要从模块中导出它,而是附加它.对于同构使用,请使用类似......

function s() { ... }

// must cast as any to set property on window
const _global = (window /* browser */ || global /* node */) as any
_global.s = s
Run Code Online (Sandbox Code Playgroud)

你也可以抛弃.d.ts文件并使用declare global例如在同一文件中声明类型

// 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;
}
Run Code Online (Sandbox Code Playgroud)


Rom*_*eau 6

global.ts(x)只需稍作调整即可成为有效的“全局模块” (仅具有副作用的模块):删除export关键字并添加一些代码以增强全局对象。您也可以在同一文件中提供全局声明并删除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;
Run Code Online (Sandbox Code Playgroud)

要使用它,只需导入模块一次,例如App.tsx通过global import:即可import './global';

经过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);
    });
});
Run Code Online (Sandbox Code Playgroud)


kan*_*nji 6

感谢@Romain Deneau。他的回答对我有用。这是我的简化版,以便更容易理解他的答案。(我的假设脚本在浏览器上运行。另外,我省略了函数的签名s。)

在任何类之外定义函数。

function s() {
    console.log("invoked s()!");
}

(window as any).s = s;
Run Code Online (Sandbox Code Playgroud)

使用sTypeScript 类中的这个全局函数如下所示;

declare var s;

export class MyClass {
    public static callFunctionS() {
        s();
    }
}
Run Code Online (Sandbox Code Playgroud)