Menu

TypeScript Namespace Nedir, Ne Zaman Kullanılır

Bir TypeScript namespace'i değerleri ve tipleri tek bir ad altında toplar ve düz bir nesneye derlenir. Söz dizimini, namespace'lerin birbirleriyle ve fonksiyon ve class'larla nasıl birleştiğini, ES modüllerinin neden onların yerini aldığını ve onlarla hâlâ nerede karşılaştığınızı öğrenin: declaration dosyaları ve global augmentation.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Namespace, fonksiyonları, sabitleri ve tipleri tek bir ad altında toplayan adlandırılmış bir bloktur. export ile işaretlenen üyelere Name.member biçiminde erişilir; geri kalanı bloğa özel kalır. Çalışma zamanında bir namespace düz bir nesnedir.

Bir Namespace Neye Derlenir

Namespace'ler, kod üreten az sayıdaki TypeScript özelliğinden biridir. Yukarıdaki blok, bir nesneyi dolduran bir fonksiyona dönüşür:

var Geometry;
(function (Geometry) {
    const TAU = Math.PI * 2;
    function circumference(radius) {
        return TAU * radius;
    }
    Geometry.circumference = circumference;
    function area(radius) {
        return Math.PI * radius ** 2;
    }
    Geometry.area = area;
})(Geometry || (Geometry = {}));

Bu, modüller var olmadan önce JavaScript kodunun her adı global kapsama koymamak için kullandığı kalıptır. TAU fonksiyonun yerel bir değişkenidir, diğer kodun onu görememesinin nedeni budur. Onu okumaya çalışmak bir derleme zamanı hatasıdır:

Derleyici şunu bildirir: index.ts(10,17): error TS2339: Property 'rate' does not exist on type 'typeof Tax'. const rate önüne export ekleyin, iki satır da çalışır.

İç İçe Yapı, Birleşme ve Takma Adlar

Namespace'ler iç içe olabilir ve aynı adlı iki blok tek bir blokta birleşir. Çıktıdaki Geometry || (Geometry = {}) bunu mümkün kılar: ikinci blok var olan nesneye ekleme yapar. import X = A.B kısa bir takma ad oluşturur.

namespace A.B.C { }, iç içe üç blok için bir kısaltmadır. Eski module Shop { } yazımı aynı anlama gelir ama artık TS1540 hatasıyla reddedilir: A 'namespace' declaration should not be declared using the 'module' keyword. Please use the 'namespace' keyword instead.

Fonksiyon ve Class'larla Birleşme

Bir namespace adını bir fonksiyon, class ya da enum ile paylaşabilir ve ona üye ekleyebilir. Bu, aynı zamanda özellik taşıyan bir fonksiyonu ya da yardımcıları eklenmiş bir class'ı tanımlamanın hâlâ en temiz yoludur.

Bir class için static bir metot aynı işi görür ve düz JavaScript'tir. Bir fonksiyon için namespace'i atlayıp tanımın hemen ardından format.prefix = "$" ataması da yapabilirsiniz; TypeScript bu şekilde atanan özellikleri izler.

Namespace ve Modül

ES modüllerinden önce büyük bir TypeScript programı, global namespace'leri paylaşan, /// <reference path="..." /> ile birbirine bağlanan ve outFile ile tek bir dosyaya derlenen birçok script dosyasından oluşurdu. Modüller bunun yerini aldı: her dosya kendi kapsamıdır, bağımlılıklar açık import'lardır ve bundler'lar kullanılmayan export'ları atabilir. TypeScript 7 outFile seçeneğini kaldırdı (TS5102 hatası), bu yüzden çok dosyalı namespace kurulumu artık bir build seçeneği değil.

NamespaceModül
Birimbir dosyadaki adlandırılmış bir blokdosyanın kendisi
Kapsambir modülün içinde değilse globalher zaman kendine ait
Bağımlılıklarörtük, yükleme sırasına göreaçık import
Çıktıbir fonksiyonun oluşturduğu bir nesneimport/export ya da require
Kullanılmayan kodun silinmesibundler'lar her üyeyi tutarbundler'lar kullanılmayan export'ları atabilir
Node type stripping altında çalışır mıyalnızca sadece tip içeriyorsaevet

Bir modülün içinde her şeyi bir namespace'e sarmak hiçbir kazanç olmadan ikinci bir adlandırma seviyesi ekler: import edenler Utils.Utils.format yazmak zorunda kalır. Fonksiyonları doğrudan export edin ve bir önek isteyen import eden import * as Utils from "./utils.js" seçsin.

Namespace'lerle Hâlâ Nerede Karşılaşırsınız

Declaration dosyaları, tek bir global nesne sunan kütüphaneleri tanımlamak ve tipleri gruplamak için onları kullanır:

// jquery-like.d.ts: a global function that also has properties
declare function $(selector: string): unknown;
declare namespace $ {
    const version: string;
    function ajax(url: string): Promise<unknown>;
}

Tip paketleri, genişletebileceğiniz tipleri sunmak için onları kullanır. @types/node, namespace NodeJS tanımlar ve herhangi bir modülden onun ProcessEnv interface'ine ekleme yapmak declare global gerektirir:

// env.d.ts
export {};

declare global {
    namespace NodeJS {
        interface ProcessEnv {
            API_URL: string; // process.env.API_URL is now string, not string | undefined
        }
    }
}

Birleşen namespace'lerin içindeki interface'ler de birleşir; bu augmentation'ı çalıştıran şey budur.

Namespace'ler ve Type Stripping

Node 24, .ts dosyalarını tip söz dizimini silerek çalıştırır. Değer içeren bir namespace silinemez, yukarıda gösterilen nesneye derlenmesi gerekir; bu yüzden node app.ts şu hatayla durur:

SyntaxError [ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX]: TypeScript namespace declaration is not supported in strip-only mode

İki tür namespace sorun çıkarmaz, çünkü tamamen kaybolurlar: bir declare namespace ve bütün üyeleri tip ya da interface olan bir namespace. erasableSyntaxOnly: true derleyici seçeneği diğerlerini derleme zamanında TS1294 hatası olarak bildirir (This syntax is not allowed when 'erasableSyntaxOnly' is enabled.); type stripping ile çalışan projeler onları böyle dışarıda tutar. node --experimental-transform-types ise namespace'leri deneysel bir uyarıyla derler.

Sıkça Sorulan Sorular

TypeScript'te namespace mi yoksa modül mü kullanmalıyım?

Yeni kod için modülleri (import ve export) kullanın. Her dosya zaten kendi kapsamıdır, bundler'lar ve Node modülleri anlar ve kullanılmayan export'lar silinebilir. Namespace'ler declaration dosyalarında, global augmentation için ve aynı adlı bir fonksiyona ya da class'a tip veya yardımcı eklemek için hâlâ işe yarar.

Bir TypeScript namespace'i neye derlenir?

Hemen çağrılan bir fonksiyonun doldurduğu bir nesneye: var Geometry; (function (Geometry) { Geometry.circle = circle; })(Geometry || (Geometry = {}));. Export edilen üyeler o nesnenin özellikleri olur; export olmayan üyeler fonksiyonun yerel değişkeni olarak kalır.

TypeScript'te namespace ile module arasındaki fark nedir?

Modül, en üst seviyede bir import ya da export içeren bir dosyadır. Namespace ise bir dosyanın içindeki adlandırılmış bir bloktur. Eski TypeScript namespace'lere "internal module" derdi ve module Foo {} yazımına izin verirdi; bu yazım artık TS1540 hatasıdır ve yalnızca namespace Foo {} kabul edilir.

Node namespace kullanan TypeScript dosyalarını çalıştırabilir mi?

Varsayılan type stripping ile hayır. Değer içeren bir namespace ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX üretir, çünkü stripping yalnızca tipleri siler, namespace ise üretilmiş kod gerektirir. Yalnızca tip içeren namespace'ler ve declare namespace silinir ve sorunsuz çalışır.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA