Kako definirati globalnu funkciju u TypeScriptu?
Želim definirati globalnu funkciju koja je dostupna svugdje, bez potrebe za uvozom modula kada se koristi.
Ova funkcija ima za cilj zamijeniti operater sigurne navigacije (?) dostupan u C#. Radi preglednosti, ne želim prefiksirati funkciju imenom modula.
Global.d.ts:
declare function s<T>(someObject: T | null | undefined, defaultValue?: T | null | undefined) : T;
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;
}
App.tsx (glavna TypeScript datoteka):
import 'Global';
Druga TSX datoteka (korištenje metode):
s(s(nullableVar).member).member; //Runtime error
Ovo se dobro kompajlira, međutim, u pregledniku ovo baca 's nije funkcija'.
Odgovor #1
Definirate tip za prevoditelja, ali ga zapravo ne pridružujete globalnom prostoru imena — window u pregledniku, global u nodeu. Umjesto da ga izvozite iz modula, pridružite ga. Za izomorfnu upotrebu, koristite nešto poput...
function s() { ... }
// must cast as any to set property on window
const _global = (window /* browser */ || global /* node */) as any
_global.s = s
Također možete odbaciti .d.ts datoteku i deklarirati tip u istoj datoteci koristeći declare global, npr.
// 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;
}
Odgovor #2
Hvala @Romain Deneau. Njegov odgovor je kod mene proradio. Evo mog pojednostavljenog da izgleda lakše za razumjeti poantu njegovog odgovora. (Moj pretpostavlja da se skripte izvode u pregledniku. Također, izostavio sam potpis funkcije s.)
Definirajte funkciju izvan bilo koje klase.
function s() {
console.log("invoked s()!");
}
(window as any).s = s;
Korištenje ove globalne funkcije s iz TypeScript klase izgleda ovako;
declare var s;
export class MyClass {
public static callFunctionS() {
s();
}
}
Odgovor #3
global.ts(x) treba samo malo prilagodbe da bude važeći "globalni modul" (modul samo s nuspojavama): uklonite ključnu riječ export i dodajte neki kod za proširenje globalnog objekta. Također možete pružiti globalnu deklaraciju u istoj datoteci i ukloniti 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;
Za njegovo korištenje, samo jednom uvezite modul, na primjer u App.tsx putem globalnog uvoza: import './global';.
Testirano s 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);
});
});
