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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47736473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:49:33  来源:igfitidea点击:

How to define global function in TypeScript?

typescript

提问by sixtstorm1

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 operator (?) available in C#. For the sake of readability, I don't want to prefix the function with a module name.

此函数旨在替换 C# 中可用的安全导航运算符 (?)。为了可读性,我不想在函数前加上模块名。

Global.d.ts:

全球.d.t​​s:

declare function s<T>(someObject: T | null | undefined, defaultValue?: T | null | undefined) : T;

Global.tsx:

全球.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;
}

App.tsx (root TypeScript file):

App.tsx(根 TypeScript 文件):

import 'Global';

Other TSX file (method usage):

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

s(s(nullableVar).member).member; //Runtime error

This compiles fine, however, in the browser this throws 's is not a function'.

这编译得很好,但是,在浏览器中这会抛出“ s is not a function”。

回答by caseyWebb

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

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

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.tsfile and declare the type in the same file using declare global, e.g.

您还可以放弃.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;
}

回答by Romain Deneau

global.ts(x)needs just a little tweak to be a valid "global module" (a module with side effects only): remove the exportkeyword 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.

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;

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

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

Tested with mocha, chai, ts-node:

用 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);
    });
});

回答by kanji

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.)

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

Define function outside of any class.

在任何类之外定义函数。

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

(window as any).s = s;

Using this global function sfrom TypeScript class is like below;

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

declare var s;

export class MyClass {
    public static callFunctionS() {
        s();
    }
}