जर तुम्ही कधीही TypeScript monorepo मध्ये दोन ओळींचा bugfix push केला असेल आणि तुमचा build pipeline दहा मिनिटे type checking मध्ये घालवताना पाहिला असेल, तर तुम्हाला समस्या आधीच समजली असेल. हा विलंब bundling मुळे नाहीये. तो minification मुळेही नाहीये. हा तो क्षण आहे जेव्हा TypeScript तुमच्या declaration files लिहिण्याचा प्रयत्न करते. एक .d.ts फाईल emit करण्यापूर्वी, compiler ला संपूर्ण type graph resolve करावा लागतो. तो imports शोधतो, generics तपासतो आणि अशा return types चा अंदाज लावतो (infer करतो) जे कदाचित तीन dependency layers खोल असू शकतात. तुम्ही बदललेली ती एक फाईल दुसऱ्या फाईलला स्पर्श करते, जी तिसऱ्याला स्पर्श करते, आणि अचानक तुमचा function काय return करते हे सांगण्यासाठी compiler संपूर्ण repository मध्ये तपासकार्य (detective work) करू लागतो.
TypeScript 6.0 मध्ये ही सवय मोडण्यासाठी isolatedDeclarations आणले आहे.
मुख्य अडथळा
Declaration files हे तुमच्या कोडचे public contract असतात. जेव्हा दुसरा developer तुमचा package import करतो, तेव्हा TypeScript source ऐवजी .d.ts files वाचते. त्या files अचूकपणे तयार करण्यासाठी compiler ला type checker वगळता चालत नाही. आउटपुटची एक ओळ लिहिण्यापूर्वी त्याला प्रत्येक shape, प्रत्येक union आणि प्रत्येक inferred return type माहित असणे आवश्यक आहे.
पन्नास फाईल्स असलेल्या लहान प्रोजेक्टमध्ये हे लगेच होते. हजारो modules असलेल्या मोठ्या monorepo मध्ये, हे एकमागून एक येणारा nightmare ठरते. एखाद्या core package मधील utility type बदला, आणि compiler प्रत्येक consumer कडे पुन्हा जाऊन हे तपासतो की inferred types अजूनही योग्य आहेत की नाही. Build time फक्त फाईल्सच्या संख्येवर नाही, तर dependency च्या खोलीवर (depth) अवलंबून असतो. एक साधे refactor देखील संपूर्ण graph ची पुन्हा गणना (recomputation) सुरू करू शकते. टीम्स अनेकदा हे अपरिहार्य मानून स्वीकारतात. पण ते तसे नाहीये.
isolatedDeclarations कसे काम करते
हा नवीन flag तुमच्या आणि compiler मधील करार (contract) बदलतो. TypeScript ला तुमच्या exports चे types infer करण्यास सांगण्याऐवजी, तुम्ही स्वतः त्यांना annotate करता. या एका बदलामुळे global knowledge ची गरज संपते. तुमच्या module साठी declarations emit करण्यासाठी compiler ला आता तुमच्या dependencies चे विश्लेषण करण्याची गरज नाही. तो फक्त त्याच्या समोर असलेल्या syntax कडे पाहतो.
याचा अर्थ असा की प्रत्येक फाईल तिचे .d.ts output स्वतंत्रपणे आणि समांतर (in parallel) emit करू शकते. Declaration generation सुरू करण्यापूर्वी build tool ला संपूर्ण type graph तयार करण्याची गरज नसते. esbuild आणि swc सारखी टूल्स, जी पूर्वी type checker नसल्यामुळे .d.ts emit करणे टाळत असत, ती आता transpilation च्या जवळच्या वेगाने declarations तयार करू शकतात. ती थेट source मधून explicit annotations वाचतात आणि कोणतेही type equations न सोडवता संबंधित type definitions लिहितात.
पूर्वी, declaration emit वर tsc ची मक्तेदारी होती कारण फक्त official compiler कडेच .d.ts files तयार करण्यासाठी आवश्यक असलेली type information होती. Fast transpilers types काढून टाकू शकत होते किंवा syntax बदलू शकत होते, पण ते type definitions तयार करू शकत नव्हते. isolatedDeclarations मुळे संपूर्ण ecosystem साठी declaration workflows हाताळण्याचे दरवाजे उघडले आहेत. हे रूपांतर logical ऐवजी mechanical होते. याच फरकामुळे दहा मिनिटांची प्रतीक्षा काही सेकंदात बदलली जाते.
तडजोड: Explicit हेच नवीन Default आहे
वेगासोबत एक स्पष्ट किंमत येते. प्रत्येक exported function, class आणि variable मध्ये explicit type annotation असणे आवश्यक आहे. TypeScript तुमच्यासाठी public API infer करण्यास नकार देईल.
एका साध्या utility चा विचार करा:
export function getUser(id: number) {
return fetchUser(id);
}
isolatedDeclarations सक्षम असल्यास, यामध्ये error येईल. compiler ला fetchUser ची तपासणी केल्याशिवाय त्याचा return type कळू शकत नाही, आणि या flag अंतर्गत
