TypeScript में DSL: एक शाम में अपनी प्रोग्रामिंग भाषा बनाएँ

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

आपका प्रोजेक्ट अपनी खुद की भाषा का हकदार क्यों है?

\n\n

कल्पना करें: आप बीमा प्रीमियम की गणना के लिए कोड लिख रहे हैं, और दर्जनों नेस्टेड if-else और मैजिक नंबरों के बजाय, आप एक संक्षिप्त संरचना देखते हैं:

\n\n
const rule = new InsuranceRule()\n  .when(age > 25)\n  .and(experience > 2)\n  .then(premium = base * 0.8);
\n\n

यह जादू नहीं है। यह DSL (Domain Specific Language) है — TypeScript में निर्मित एक डोमेन-विशिष्ट भाषा। इस लेख में, हम जानेंगे कि ऐसी भाषाएँ कैसे बनाई जाती हैं, ताकि आपका कोड व्यवसाय की भाषा में बोले, न कि मशीनों की भाषा में।

\n\n

DSL क्या है और इसकी आवश्यकता क्यों है?

\n\n

DSL एक ऐसी भाषा है जो किसी एक विशिष्ट डोमेन की समस्याओं को हल करने के लिए बनाई गई है। सामान्य-उद्देश्य वाली भाषाओं (Java, C#, TypeScript) के विपरीत, DSL सार्वभौमिक होने का प्रयास नहीं करता। यह अभिव्यक्ति के लिए लचीलापन त्याग देता है।

\n\n

DSL का उपयोग कब करें:

\n
    \n
  • व्यावसायिक तर्क अक्सर बदलता है और इसे विश्लेषकों द्वारा संपादित करने की आवश्यकता होती है
  • \n
  • प्रोजेक्ट में कई दोहराए जाने वाले कॉन्फ़िगरेशन पैटर्न हैं
  • \n
  • जटिल एल्गोरिदम को बाकी कोड से अलग करने की आवश्यकता है
  • \n
  • व्याकरण के स्तर पर डेटा सत्यापन की आवश्यकता है
  • \n
\n\n

DSL बनाने के लिए TypeScript एक आदर्श विकल्प है। स्थैतिक टाइपिंग, एक शक्तिशाली टाइप सिस्टम, और JavaScript में संकलित होने की क्षमता इसे आंतरिक और बाह्य दोनों भाषाओं के निर्माण के लिए एक लचीला उपकरण बनाती है।

\n\n

आंतरिक DSL: fluent API और कॉल चेन

\n\n

TypeScript में DSL बनाने का सबसे सरल तरीका Fluent Interface (प्रवाहपूर्ण इंटरफ़ेस) का उपयोग करना है। इसमें प्रत्येक विधि स्वयं ऑब्जेक्ट को लौटाती है, जिससे कॉल की चेन बनाई जा सकती है।

\n\n

उदाहरण: SQL क्वेरी कंस्ट्रक्टर

\n\n
class QueryBuilder {\n  private table: string = '';\n  private conditions: string[] = [];\n  private selectedFields: string[] = ['*'];\n\n  select(...fields: string[]): this {\n    this.selectedFields = fields.length ? fields : ['*'];\n    return this;\n  }\n\n  from(table: string): this {\n    this.table = table;\n    return this;\n  }\n\n  where(condition: string): this {\n    this.conditions.push(condition);\n    return this;\n  }\n\n  and(condition: string): this {\n    return this.where(condition);\n  }\n\n  build(): string {\n    let sql = `SELECT ${this.selectedFields.join(', ')} FROM ${this.table}`;\n    if (this.conditions.length) {\n      sql += ` WHERE ${this.conditions.join(' AND ')}`;\n    }\n    return sql;\n  }\n}\n\n// उपयोग\nconst query = new QueryBuilder()\n  .select('name', 'age')\n  .from('users')\n  .where('age > 18')\n  .and('status = "active"')\n  .build();\n\nconsole.log(query);\n// SELECT name, age FROM users WHERE age > 18 AND status = "active"
\n\n

यह एक क्लासिक TypeScript में आंतरिक DSL है। इसे अलग पार्सर की आवश्यकता नहीं है और यह TypeScript कोड के अंदर काम करता है। मुख्य लाभ ऑटो-कम्प्लीशन और टाइपिंग का पूर्ण समर्थन है।

\n\n

जटिल बनाना: व्यावसायिक नियमों के लिए टाइप किया गया DSL

\n\n

जेनेरिक और यूनियन प्रकारों के साथ सख्त टाइपिंग जोड़ें:

\n\n
type ComparisonOperator = '>' | '<' | '=' | '!=';\n\nclass RuleBuilder<T extends Record<string, any>> {\n  private conditions: ((data: T) => boolean)[] = [];\n\n  when<K extends keyof T>(field: K, op: ComparisonOperator, value: T[K]): this {\n    this.conditions.push((data: T) => {\n      switch (op) {\n        case '>': return data[field] > value;\n        case '<': return data[field] < value;\n        case '=': return data[field] === value;\n        case '!=': return data[field] !== value;\n      }\n    });\n    return this;\n  }\n\n  and<K extends keyof T>(field: K, op: ComparisonOperator, value: T[K]): this {\n    return this.when(field, op, value);\n  }\n\n  evaluate(data: T): boolean {\n    return this.conditions.every(c => c(data));\n  }\n}\n\n// जाँच के लिए डेटा प्रकार\ninterface UserData                

ब्लॉग

पुस्तक अनुशंसाएँ