यदि आप ऐसी सुविधा पर निर्भरता लेने के इच्छुक हैं जो जल्द से जल्द बदलने की संभावना है, क्योंकि यह अप्रचलित विनिर्देश पर आधारित है, और यदि आप केवल कक्षाओं का उपयोग करने के इच्छुक हैं और इंटरफ़ेस नहीं हैं, तो आप इसका उपयोग करके इसे पूरा कर सकते हैं एक सजावटी
यहाँ एक उदाहरण है:
पदानुक्रम-tracked.ts
export default function hierarchyTracked(target: new (...args: any[]) => object) {
for (const proto of walkPrototypeChain(target)) {
if (!Object.hasOwnProperty.call(proto, 'extendedBy')) {
const extendedBy: typeof Function.extendedBy = [];
Object.defineProperty(proto, 'extendedBy', {
get:() => extendedBy
});
}
// ! is used to suppress a strictNullChecks error on optional.
// This is OK since we know it is now defined.
proto.extendedBy!.push(target);
}
}
declare global {
interface Function {
// Declared as optional because not all classes are extended.
extendedBy?: Array<new (...args: any[]) => object>;
}
}
function* walkPrototypeChain(target: new (...args: any[]) => object) {
let proto = Reflect.getPrototypeOf(target);
while (proto && proto !== Object) {
yield proto;
proto = Reflect.getPrototypeOf(proto);
}
}
animals.ts
import hierarchyTracked from './hierarachy-tracked';
export class Animal {
alive = true;
static get slayable() {return true;}
static extinct = false;
}
@hierarchyTracked export class Snake extends Animal {
isEctotherm = true;
}
@hierarchyTracked export class Cobra extends Snake {
isDeadly = true;
}
@hierarchyTracked export class Horse extends Animal {
isEndotherm = true;
}
// logs
Animal.extendedBy && Animal.extendedBy.map(Taxon => Taxon.name)
.forEach(name => {
console.log(name);
});
// Snake
// Cobra
// Horse
Snake.extendedBy && Snake.extendedBy.map(Taxon => Taxon.name)
.forEach(name => {
console.log(name);
});
// Cobra
वैश्विक राज्य और इसे करने के लिए उपाय करने की जरूरत नहीं है वास्तव में काफी साफ और स्पष्ट है।
यदि आप टाइपस्क्रिप्ट का उपयोग नहीं कर रहे हैं तो यह Babel 7 के साथ भी काम करता है। (ध्यान दें कि डेकोरेटर उपयोग के बारे में एक ही चेतावनियां ऊपर उल्लेख किया है अभी भी लागू)
बेशक
इस मैन्युअल रूप से लिखने के लिए मामूली बात है अगर तुम नहीं करते सज्जाकार पर भरोसा करना चाहते हैं: ऊपर
import trackHierarchy from './hierarachy-tracked';
export class Animal { }
class Snake extends Animal { ... }
trackHierarchy(Snake);
export {Snake};
अपने उदाहरण कोड पर वापस, यह आसानी से हासिल किया जाता है।
यह
var childTypes = assembly.GetTypes().Where(_ => _.IsSubclassOf(typeof(Animal)));
से चला जाता है बस
const childClasses = Animal.extendedBy || [];
एक चेतावनी
का वचन आप पाते हैं अपने आप को इस तरह कोड लिखने के लिए इच्छुक हैं, तो आप एक कदम पीछे ले जाना चाहिए करने के लिए और सुनिश्चित करें कि आप वास्तव में जावास्क्रिप्ट जानते हैं। इस तरह के पैटर्न, और वास्तव में आपका उदाहरण उपयोग केस, आमतौर पर इंगित करता है कि कोई शास्त्रीय मानसिकता के साथ भाषा में आया है, ईएस 2015 कक्षाओं को देखा है, और यह सोचने लगा कि वे पारंपरिक भाषाओं में कक्षाओं से संबंधित हैं।
ईएस कक्षाएं सी #, सी ++, जावा, या स्कैला कक्षाओं की तरह कम नहीं हो सकतीं।
पहला और सबसे महत्वपूर्ण: जावास्क्रिप्ट में कक्षाएं प्रकार नहीं हैं।
जावास्क्रिप्ट में कक्षाएं मान हैं।
उनका घोषणा फॉर्म मूल रूप से प्रोटोटाइप पर एक वाक्य रचनात्मक चीनी है। जिस पैटर्न को आप प्राप्त करने की कोशिश कर रहे हैं, वह सुझाव देता है कि आप इसे अच्छी तरह से समझ नहीं सकते हैं। विशेष रूप से, यह सुझाव देता है कि आप सोच सकते हैं कि वे विशेष हैं।
यह वर्तमान में एक [गैर-लक्ष्य] (https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals) टाइपस्क्रिप्ट के लिए है। आप जिस वास्तविक समस्या को हल करने की कोशिश कर रहे हैं वह क्या है? –
टाइपस्क्रिप्ट में अपनी कक्षाएं बनाने के लिए https://frhagn.github.io/Typewriter/ का उपयोग करने के बारे में कैसे? –
@PaulBullivant मुझे वह उपकरण पसंद है लेकिन मुझे लगता है कि वह कुछ अलग दिख रहा है –