TypeScript'te global bir değişken oluşturun


93

JavaScript'te şunu yapabilirim:

 something = 'testing';

Ve sonra başka bir dosyada:

 if (something === 'testing')

ve somethingtanımlanmış olacaktır (doğru sırada çağrıldıkları sürece).

Bunu TypeScript'te nasıl yapacağımı çözemiyorum.

Bu denediğim şey.

.D.ts dosyasında:

interface Window { something: string; }

Sonra main.ts dosyamda:

 window.something = 'testing';

sonra başka bir dosyada:

 if (window.something  === 'testing')

Ve bu işe yarar. Ama bunun bir window.kısmını kaybedebilmek ve sadece somethingküresel olmak istiyorum . Bunu TypeScript'te yapmanın bir yolu var mı?

(Birisinin ilgilenmesi durumunda, gerçekten uygulamam için günlüğe kaydetmemi ayarlamaya çalışıyorum. log.DebugNesneleri içe aktarmak ve oluşturmak zorunda kalmadan herhangi bir dosyadan çağrı yapabilmek istiyorum .)

Yanıtlar:


4

Tamam, yani bu muhtemelen yaptığınız şeyden daha çirkin, ama neyse ...

ama ben de aynısını yapıyorum ...

Bunu saf TypeScript ile yapmak için yapabileceğiniz şey, evalişlevi şu şekilde kullanmaktır :

declare var something: string;
eval("something = 'testing';")

Ve sonra yapabileceksin

if (something === 'testing')

Bu, TypeScript'in derlemeyi reddetmeden talimatı yürütmeye zorlamaktan başka bir şey değildir ve declare varTypeScript'in kodun geri kalanını derlemesini istiyoruz.


Bu benim için çalışmıyor. Eval ('myglobalvar = {};'); var. Sonuç: Yakalanmamış Referans Hatası: myglobalvar eval'da tanımlanmadı (<anonymous> olarak değerlendir .....). Tuhaf bir şekilde konsoldan çalıştırırsam işe yarıyor.
Ryan How

2
@DragonRock Chrome ve FF'yi denedim. Bu yüzden neler olup bittiğinden gerçekten emin değilim. Neyse, deklare var myglobalvar yapıyor sona erdi; (<herhangi> pencere) .myglobalvar = {}; Daha sonra penceresiz referans verebilirim.
Ryan How

2
Bu gerçekten bir .d.tstanım dosyasıyla yapılmalıdır .
brianespinosa

2
Bu benim için çalışıyor:export declare const SERVER = "10.1.1.26";
xinthose

2
Kullanılması evalkesinlikle tavsiye edilmez, bu yüzden bu çözüm stackoverflow.com/a/56984504/5506278
Yaroslav Bai

62

Bir .d.tstanım dosyasının içinde

type MyGlobalFunctionType = (name: string) => void

Tarayıcıda çalışıyorsanız, tarayıcının pencere bağlamına üye eklersiniz:

interface Window {
  myGlobalFunction: MyGlobalFunctionType
}

NodeJS için aynı fikir:

declare module NodeJS {
  interface Global {
    myGlobalFunction: MyGlobalFunctionType
  }
}

Şimdi kök değişkeni (aslında pencerede veya globalde yaşayacak olan) bildirirsiniz

declare const myGlobalFunction: MyGlobalFunctionType;

Daha sonra normal bir .tsdosyada, ancak yan etki olarak içe aktarıldığında, aslında onu uygularsınız:

global/* or window */.myGlobalFunction = function (name: string) {
  console.log("Hey !", name);
};

Ve son olarak kod tabanında başka bir yerde, şunlardan biriyle kullanın:

global/* or window */.myGlobalFunction("Kevin");

myGlobalFunction("Kevin");

4
(Sadece geçen bir yorumda bulunarak) Basit bir global değişken oluşturmak için çok çalışmadan bahsedin! lol
Pytth

6
@Benoit "Ama yan etki olarak ithal edildi" yazan kısmı alamıyorum. Bununla ne demek istiyorsun?. Bunu yapmayı denedim ama benim için çalışmıyor, bir kaynak kod örneği paylaşabilir misiniz?
BernalCarlos

Bu cezasını çalışır .tsdosyaları ama kullanırken window.myGlobalFunctionbenim de .tsxdosyalar, öyle değil. Değiştirmek için başka neye ihtiyacım var ?!
Kousha

13
D.ts dosyasını nereye yerleştirirsiniz ve TypeScript'i yüklemek için nasıl yapılandırırsınız?
Matthias

26

globalBu gelecek.

İlk olarak, TypeScript dosyalarında iki tür scopes

küresel kapsam

Dosyanızda hiç importveya exportsatır yoksa , bu dosya genel kapsamda yürütülecektir. tüm bildirimler bu dosyanın dışında görünür.

Dolayısıyla, şu şekilde küresel değişkenler oluşturabiliriz:

// xx.d.ts
declare var age: number

// or 
// xx.ts
// with or without declare keyword
var age: number

// other.ts
globalThis.age = 18 // no error

Tüm sihir gelir var. Değiştir varile letya constçalışmaz.

modül kapsamı

Dosyanız herhangi varsa importveya exportçizgi , bu dosya biz küresel uzatmak gerektiğini kendi kapsamında yürütülecek olurdu beyan-birleştiği .

// xx[.d].ts
declare global {
  var age: number;
}

// other.ts
globalThis.age = 18 // no error

Modül hakkında daha fazlasını resmi belgelerde görebilirsiniz


Ama bunu 'var' hack olmadan nasıl yaparsınız? Sanırım bu, globalThis'te yazım büyütmeyi nasıl yapabilirim?
Tom

1
@Tom vargerekli. Ancak değişkeni başlatmadan da
bildirebilirsiniz

Benim için çalıştı (en azından şimdilik) çok teşekkürler, bu cevabın yükselmesini diliyorum. Bilginize: Benim durumumda linter // @ts-ignoreiçin globalThisçizginin üstüne eklemem gerekiyordu .
David

Herhangi bir typcript dosyasına yaş değişkenini nasıl çağırırsınız?
Ashok kumar Ganesan

18

Bunu şu şekilde düzelttim:

Adımlar:

  1. Aşağıdaki gibi custom.d.ts için genel bir ad alanı bildirildi:
declare global {
    namespace NodeJS {
        interface Global {
            Config: {}
        }
    }
}
export default global;
  1. Yukarıda oluşturulmuş olan dosyayı "tsconfig.json" ile aşağıdaki gibi eşleyin:
"typeRoots": ["src/types/custom.d.ts" ]
  1. Aşağıdaki dosyalardan herhangi birinde yukarıda oluşturulan global değişkeni alın:
console.log(global.config)

Not:

  1. typescript sürümü: "3.0.1".

  2. Benim durumumda gereksinim, uygulamayı başlatmadan önce global değişkeni ayarlamaktı ve değişken, gerekli yapılandırma özelliklerini alabilmemiz için bağımlı nesnelerin tamamına erişmelidir.

Bu yardımcı olur umarım!

teşekkür ederim


14

TypeScript ile birlikte JavaScript kullanırsam işe yarayan bir yol buldum.

logging.d.ts:

declare var log: log4javascript.Logger;

günlük beyanı. js :

log = null;

initalize-app.ts

import './log-declaration.js';

// Call stuff to actually setup log.  
// Similar to this:
log = functionToSetupLog();

Bu, onu genel kapsam içine alır ve TypeScript bunu bilir. Böylece tüm dosyalarımda kullanabilirim.

NOT: Bunun işe yaradığını düşünüyorum çünkü allowJsTypeScript seçeneğim true olarak ayarlanmış.

Birisi saf bir TypeScript çözümü yayınlarsa, bunu kabul ederim.


1
İnitalize-app.ts dosyanızda şunları kullanabilirsiniz: declare var log: any; O zaman d.ts dosyasına veya js dosyasına sahip olmanız gerekmez. Herhangi birini gerçek bir türle veya bir arabirim tanımıyla değiştirebilirsiniz.
mattferderer

5

sadece bunu kullanıyorum

import {globalVar} from "./globals";
declare let window:any;
window.globalVar = globalVar;

1
Bu, tüm tür bilgileri atar. Javascript kullanabilir de.
Timmmm

3

Bunu yapmanın doğru yolunu bulmak için birkaç saat harcadım. Benim durumumda global "log" değişkenini tanımlamaya çalışıyorum, bu nedenle adımlar şunlardı:

1) tsconfig.jsontanımladığınız türleri içerecek şekilde yapılandırın ( src/typesklasör, node_modules - size bağlıdır):

...other stuff...
"paths": {
  "*": ["node_modules/*", "src/types/*"]
}

2) src/types/global.d.tsaşağıdaki içeriğe sahip bir dosya oluşturun ( içe aktarma yok! - bu önemlidir), tarayıcıyla çalışıyorsanız any, ihtiyaçlarınıza uyacak şekilde değiştirmekten çekinmeyin + windowarayüzü kullanın NodeJS:

/**
 * IMPORTANT - do not use imports in this file!
 * It will break global definition.
 */
declare namespace NodeJS {
    export interface Global {
        log: any;
    }
}

declare var log: any;

3) artık nihayet logihtiyaç duyduğunuz yerde kullanabilir / uygulayabilirsiniz :

// in one file
global.log = someCoolLogger();
// in another file
log.info('hello world');
// or if its a variable
global.log = 'INFO'

Ne var pathsiçinde tsconfig.json? Doktorlarda bundan bahsedilmiyor.
tambre

Ve neden Globaltanımlarda büyük harfle yazılıyor, ancak gerçek kullanımda değil?
tambre

@tambre TS belgelerinde neden belgelenmediğinden emin değil, bu yapılandırmayla ilgili bazı ayrıntıları burada bulabilirsiniz: json.schemastore.org/tsconfig ve burada: basarat.gitbooks.io/typescript/docs/project/tsconfig.html İlgili Globalsermaye ile - nodejs isim alanında "global" arayüz bildirimi bu şekilde adlandırılır.
Alexey

1

Lodash'ı değiştiremediğim, sadece gerektirdiğim mevcut bir .js dosyasını kullanmak için global yapmam gerekiyordu.

Bunun işe yaradığını buldum:

import * as lodash from 'lodash';

(global as any)._ = lodash;

0

Dima V'in cevabına bir eklenti olarak, bunun benim için çalışmasını sağlamak için yaptım.

// First declare the window global outside the class

declare let window: any;

// Inside the required class method

let globVarName = window.globVarName;


Buna olumsuz oy veren kişi sebebini açıklayabilir mi?
Jonathan Cardoz

7
Bu, kontrol panelinizdeki "kontrol motoru" ışığınızın üzerine bir parça siyah bant koymak gibi bir çözümdür. Sorunu düzeltir, ancak doğru şekilde değil. Türleri yok eder. Optimal bir çözüm değil; bu aynı zamanda typcript'in ana amacı etrafında da çalışan bir geçici çözüm: türlere sahip olmak.
Matthias

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.