டைப்ஸ்கிரிப்ட்டின் வேரியன்ஸ் விரிவுரைகள் மற்றும் டைப் பாராமீட்டர் கட்டுப்பாடுகளின் ஆற்றலைப் பயன்படுத்தி, மிகவும் நெகிழ்வான, பாதுகாப்பான, மற்றும் பராமரிக்கக்கூடிய கோடை உருவாக்குங்கள். நடைமுறை எடுத்துக்காட்டுகளுடன் ஒரு ஆழமான பார்வை.
டைப்ஸ்கிரிப்ட் வேரியன்ஸ் விரிவுரைகள்: வலுவான கோடை உருவாக்க டைப் பாராமீட்டர் கட்டுப்பாடுகளில் தேர்ச்சி பெறுதல்
டைப்ஸ்கிரிப்ட், ஜாவாஸ்கிரிப்ட்டின் ஒரு சூப்பர்செட், ஸ்டேடிக் டைப்பிங்கை வழங்குகிறது, இது கோடின் நம்பகத்தன்மை மற்றும் பராமரிப்பை மேம்படுத்துகிறது. டைப்ஸ்கிரிப்ட்டின் மிகவும் மேம்பட்ட, ஆனாலும் சக்திவாய்ந்த அம்சங்களில் ஒன்று, டைப் பாராமீட்டர் கட்டுப்பாடுகளுடன் இணைந்து வேரியன்ஸ் விரிவுரைகளுக்கு அதன் ஆதரவு ஆகும். இந்த கருத்துக்களைப் புரிந்துகொள்வது உண்மையான வலுவான மற்றும் நெகிழ்வான ஜெனரிக் கோடை எழுதுவதற்கு முக்கியமானது. இந்த வலைப்பதிவு இடுகை வேரியன்ஸ், கோவேரியன்ஸ், கான்ட்ராவேரியன்ஸ் மற்றும் இன்வேரியன்ஸ் ஆகியவற்றை ஆழமாக ஆராய்ந்து, பாதுகாப்பான மற்றும் மீண்டும் பயன்படுத்தக்கூடிய கூறுகளை உருவாக்க டைப் பாராமீட்டர் கட்டுப்பாடுகளை எவ்வாறு திறம்படப் பயன்படுத்துவது என்பதை விளக்கும்.
வேரியன்ஸைப் புரிந்துகொள்ளுதல்
வேரியன்ஸ் என்பது, டைப்களுக்கு இடையிலான சப்டைப் உறவு எவ்வாறு கட்டமைக்கப்பட்ட டைப்களுக்கு (எ.கா., ஜெனரிக் டைப்கள்) இடையிலான சப்டைப் உறவைப் பாதிக்கிறது என்பதை விவரிக்கிறது. முக்கிய சொற்களை உடைத்துக் காண்போம்:
- கோவேரியன்ஸ்: ஒரு ஜெனரிக் டைப்
Container<T>
கோவேரியன்ட் ஆகும், எப்போதுSubtype
ஆனதுSupertype
-இன் சப்டைப்பாக இருக்குமோ, அப்போதுContainer<Subtype>
ஆனதுContainer<Supertype>
-இன் சப்டைப்பாக இருக்கும். இதை சப்டைப் உறவைப் பாதுகாப்பதாக நினையுங்கள். பல மொழிகளில் (டைப்ஸ்கிரிப்ட்டின் செயல்பாட்டு பாராமீட்டர்களில் நேரடியாக இல்லை என்றாலும்), ஜெனரிக் வரிசைகள் கோவேரியன்ட் ஆகும். உதாரணமாக,Cat
ஆனதுAnimal
-ஐ விரிவுபடுத்தினால், `Array<Cat>` ஆனது `Array<Animal>`-இன் சப்டைப் போல *நடந்துகொள்கிறது* (இருப்பினும் டைப்ஸ்கிரிப்ட்டின் டைப் சிஸ்டம் ரன்டைம் பிழைகளைத் தடுக்க வெளிப்படையான கோவேரியன்ஸைத் தவிர்க்கிறது). - கான்ட்ராவேரியன்ஸ்: ஒரு ஜெனரிக் டைப்
Container<T>
கான்ட்ராவேரியன்ட் ஆகும், எப்போதுSubtype
ஆனதுSupertype
-இன் சப்டைப்பாக இருக்குமோ, அப்போதுContainer<Supertype>
ஆனதுContainer<Subtype>
-இன் சப்டைப்பாக இருக்கும். இது சப்டைப் உறவைத் தலைகீழாக மாற்றுகிறது. செயல்பாட்டு பாராமீட்டர் டைப்கள் கான்ட்ராவேரியன்ஸைக் காட்டுகின்றன. - இன்வேரியன்ஸ்: ஒரு ஜெனரிக் டைப்
Container<T>
இன்வேரியன்ட் ஆகும்,Subtype
ஆனதுSupertype
-இன் சப்டைப்பாக இருந்தாலும்,Container<Subtype>
ஆனதுContainer<Supertype>
-இன் சப்டைப்பாகவோ அல்லது சூப்பர்டைப்பாகவோ இருக்காது. டைப்ஸ்கிரிப்ட்டின் ஜெனரிக் டைப்கள் பொதுவாக வேறுவிதமாகக் குறிப்பிடப்படாவிட்டால் இன்வேரியன்ட் ஆகும் (மறைமுகமாக, செயல்பாட்டு பாராமீட்டர் விதிகளின் மூலம் கான்ட்ராவேரியன்ஸுக்கு).
ஒரு ஒப்புமையுடன் இதை நினைவில் கொள்வது எளிது: நாய் கழுத்துப்பட்டைகளைத் தயாரிக்கும் ஒரு தொழிற்சாலையைக் கருதுங்கள். ஒரு கோவேரியன்ட் தொழிற்சாலை நாய்களுக்கான கழுத்துப்பட்டைகளைத் தயாரிக்க முடிந்தால், அது அனைத்து வகையான விலங்குகளுக்கும் கழுத்துப்பட்டைகளைத் தயாரிக்க முடியும், இது சப்டைப்பிங் உறவைப் பாதுகாக்கிறது. ஒரு கான்ட்ராவேரியன்ட் தொழிற்சாலை என்பது, நாய் கழுத்துப்பட்டைகளை உட்கொள்ள முடிந்தால், எந்த வகையான விலங்கு கழுத்துப்பட்டையையும் *உட்கொள்ள* முடியும். அந்த தொழிற்சாலை நாய் கழுத்துப்பட்டைகளுடன் மட்டுமே வேலை செய்ய முடியும் மற்றும் வேறு எதனுடனும் இல்லை என்றால், அது விலங்கு வகைக்கு இன்வேரியன்ட் ஆகும்.
வேரியன்ஸ் ஏன் முக்கியமானது?
டைப்-பாதுகாப்பான கோடை எழுத வேரியன்ஸைப் புரிந்துகொள்வது முக்கியம், குறிப்பாக ஜெனரிக்ஸைக் கையாளும் போது. கோவேரியன்ஸ் அல்லது கான்ட்ராவேரியன்ஸைத் தவறாகக் கருதினால், டைப்ஸ்கிரிப்டின் டைப் சிஸ்டம் தடுக்க வடிவமைக்கப்பட்டுள்ள ரன்டைம் பிழைகளுக்கு வழிவகுக்கும். இந்தத் தவறான உதாரணத்தைக் கவனியுங்கள் (ஜாவாஸ்கிரிப்டில், ஆனால் கருத்தை விளக்குகிறது):
// ஜாவாஸ்கிரிப்ட் உதாரணம் (விளக்கத்திற்கு மட்டும், டைப்ஸ்கிரிப்ட் அல்ல)
function modifyAnimals(animals, modifier) {
for (let i = 0; i < animals.length; i++) {
animals[i] = modifier(animals[i]);
}
}
function sound(animal) { return animal.sound(); }
function Cat(name) { this.name = name; this.sound = () => "Meow!"; }
Cat.prototype = Object.create({ sound: () => "Generic Animal Sound"});
function Animal(name) { this.name = name; this.sound = () => "Generic Animal Sound"; }
let cats = [new Cat("Whiskers"), new Cat("Mittens")];
//இந்தக் கோட் ஒரு பிழையை ஏற்படுத்தும், ஏனெனில் Animal-ஐ Cat வரிசையில் ஒதுக்குவது சரியல்ல
//modifyAnimals(cats, (animal) => new Animal("Generic"));
//இது வேலை செய்யும், ஏனெனில் Cat-ஐ Cat வரிசையில் ஒதுக்கப்படுகிறது
modifyAnimals(cats, (cat) => new Cat("Fuzzy"));
//cats.forEach(cat => console.log(cat.sound()));
இந்த ஜாவாஸ்கிரிப்ட் உதாரணம் சாத்தியமான சிக்கலை நேரடியாகக் காட்டினாலும், டைப்ஸ்கிரிப்டின் டைப் சிஸ்டம் பொதுவாக இந்த வகையான நேரடி ஒதுக்கீட்டைத் *தடுக்கிறது*. வேரியன்ஸ் ಪರಿசீலனைகள் மிகவும் சிக்கலான சூழ்நிலைகளில் முக்கியமானதாகின்றன, குறிப்பாக செயல்பாட்டு டைப்கள் மற்றும் ஜெனரிக் இன்டர்ஃபேஸ்களைக் கையாளும் போது.
டைப் பாராமீட்டர் கட்டுப்பாடுகள்
டைப் பாராமீட்டர் கட்டுப்பாடுகள், ஜெனரிக் டைப்கள் மற்றும் செயல்பாடுகளில் டைப் ஆர்குமெண்ட்களாகப் பயன்படுத்தக்கூடிய டைப்களைக் கட்டுப்படுத்த உங்களை அனுமதிக்கின்றன. அவை டைப்களுக்கு இடையிலான உறவுகளை வெளிப்படுத்தவும் சில பண்புகளைச் செயல்படுத்தவும் ஒரு வழியை வழங்குகின்றன. இது டைப் பாதுகாப்பை உறுதி செய்வதற்கும் மேலும் துல்லியமான டைப் இன்ஃபெரன்ஸை இயக்குவதற்கும் ஒரு சக்திவாய்ந்த வழிமுறையாகும்.
extends
கீவேர்ட்
டைப் பாராமீட்டர் கட்டுப்பாடுகளை வரையறுப்பதற்கான முதன்மை வழி extends
கீவேர்டைப் பயன்படுத்துவதாகும். இந்த கீவேர்ட் ஒரு டைப் பாராமீட்டர் ஒரு குறிப்பிட்ட டைப்பின் சப்டைப்பாக இருக்க வேண்டும் என்பதைக் குறிப்பிடுகிறது.
function logName<T extends { name: string }>(obj: T): void {
console.log(obj.name);
}
// சரியான பயன்பாடு
logName({ name: "Alice", age: 30 });
// பிழை: '{}' வகையின் ஆர்குமென்ட் '{ name: string; }' வகையின் பாராமீட்டருக்கு ஒதுக்கக்கூடியது அல்ல.
// logName({});
இந்த எடுத்துக்காட்டில், T
என்ற டைப் பாராமீட்டர், string
வகையின் name
பண்பைக் கொண்ட ஒரு டைப்பாகக் கட்டுப்படுத்தப்பட்டுள்ளது. இது logName
செயல்பாடு அதன் ஆர்குமென்டின் name
பண்பை பாதுகாப்பாக அணுக முடியும் என்பதை உறுதி செய்கிறது.
இன்டர்செக்ஷன் டைப்களுடன் பல கட்டுப்பாடுகள்
நீங்கள் இன்டர்செக்ஷன் டைப்களை (&
) பயன்படுத்தி பல கட்டுப்பாடுகளை இணைக்கலாம். இது ஒரு டைப் பாராமீட்டர் பல நிபந்தனைகளைப் பூர்த்தி செய்ய வேண்டும் என்பதைக் குறிப்பிட உங்களை அனுமதிக்கிறது.
interface Named {
name: string;
}
interface Aged {
age: number;
}
function logPerson<T extends Named & Aged>(person: T): void {
console.log(`Name: ${person.name}, Age: ${person.age}`);
}
// சரியான பயன்பாடு
logPerson({ name: "Bob", age: 40 });
// பிழை: '{ name: string; }' வகையின் ஆர்குமென்ட் 'Named & Aged' வகையின் பாராமீட்டருக்கு ஒதுக்கக்கூடியது அல்ல.
// '{ name: string; }' வகையில் 'age' பண்பு இல்லை, ஆனால் 'Aged' வகையில் தேவைப்படுகிறது.
// logPerson({ name: "Charlie" });
இங்கே, T
என்ற டைப் பாராமீட்டர் Named
மற்றும் Aged
ஆகிய இரண்டாகவும் இருக்கும் ஒரு டைப்பாகக் கட்டுப்படுத்தப்பட்டுள்ளது. இது logPerson
செயல்பாடு name
மற்றும் age
ஆகிய இரண்டு பண்புகளையும் பாதுகாப்பாக அணுக முடியும் என்பதை உறுதி செய்கிறது.
ஜெனரிக் கிளாஸ்களுடன் டைப் கட்டுப்பாடுகளைப் பயன்படுத்துதல்
ஜெனரிக் கிளாஸ்களுடன் பணிபுரியும் போது டைப் கட்டுப்பாடுகள் சமமாகப் பயனுள்ளதாக இருக்கும்.
interface Printable {
print(): void;
}
class Document<T extends Printable> {
content: T;
constructor(content: T) {
this.content = content;
}
printDocument(): void {
this.content.print();
}
}
class Invoice implements Printable {
invoiceNumber: string;
constructor(invoiceNumber: string) {
this.invoiceNumber = invoiceNumber;
}
print(): void {
console.log(`Printing invoice: ${this.invoiceNumber}`);
}
}
const myInvoice = new Invoice("INV-2023-123");
const document = new Document(myInvoice);
document.printDocument(); // வெளியீடு: Printing invoice: INV-2023-123
இந்த எடுத்துக்காட்டில், Document
கிளாஸ் ஜெனரிக்கானது, ஆனால் T
என்ற டைப் பாராமீட்டர் Printable
இன்டர்ஃபேஸைச் செயல்படுத்தும் ஒரு டைப்பாகக் கட்டுப்படுத்தப்பட்டுள்ளது. இது ஒரு Document
-இன் content
-ஆகப் பயன்படுத்தப்படும் எந்தவொரு பொருளுக்கும் print
முறை இருக்கும் என்று உத்தரவாதம் அளிக்கிறது. சர்வதேச சூழல்களில் இது குறிப்பாகப் பயனுள்ளதாக இருக்கும், அங்கு அச்சிடுதல் பல்வேறு வடிவங்கள் அல்லது மொழிகளை உள்ளடக்கியிருக்கலாம், இதற்கு ஒரு பொதுவான print
இன்டர்ஃபேஸ் தேவைப்படுகிறது.
டைப்ஸ்கிரிப்டில் கோவேரியன்ஸ், கான்ட்ராவேரியன்ஸ் மற்றும் இன்வேரியன்ஸ் (மீண்டும் ஒரு பார்வை)
டைப்ஸ்கிரிப்ட்டில் வெளிப்படையான வேரியன்ஸ் விரிவுரைகள் (சில பிற மொழிகளில் உள்ள in
மற்றும் out
போன்றவை) இல்லை என்றாலும், டைப் பாராமீட்டர்கள் எவ்வாறு பயன்படுத்தப்படுகின்றன என்பதன் அடிப்படையில் அது மறைமுகமாக வேரியன்ஸைக் கையாளுகிறது. அது எவ்வாறு செயல்படுகிறது என்பதன் நுணுக்கங்களைப் புரிந்துகொள்வது முக்கியம், குறிப்பாக செயல்பாட்டு பாராமீட்டர்களுடன்.
செயல்பாட்டு பாராமீட்டர் டைப்கள்: கான்ட்ராவேரியன்ஸ்
செயல்பாட்டு பாராமீட்டர் டைப்கள் கான்ட்ராவேரியன்ட் ஆகும். இதன் பொருள், எதிர்பார்க்கப்படுவதை விட பொதுவான டைப்பை ஏற்கும் ஒரு செயல்பாட்டை நீங்கள் பாதுகாப்பாக அனுப்பலாம். ஏனென்றால், ஒரு செயல்பாடு ஒரு Supertype
-ஐக் கையாள முடிந்தால், அது நிச்சயமாக ஒரு Subtype
-ஐக் கையாள முடியும்.
interface Animal {
name: string;
}
interface Cat extends Animal {
meow(): void;
}
function feedAnimal(animal: Animal): void {
console.log(`Feeding ${animal.name}`);
}
function feedCat(cat: Cat): void {
console.log(`Feeding ${cat.name} (a cat)`);
cat.meow();
}
// இது செல்லுபடியாகும், ஏனெனில் செயல்பாட்டு பாராமீட்டர் டைப்கள் கான்ட்ராவேரியன்ட்
let feed: (animal: Animal) => void = feedCat;
let genericAnimal:Animal = {name: "Generic Animal"};
feed(genericAnimal); // வேலை செய்யும் ஆனால் மியாவ் செய்யாது
let mittens: Cat = { name: "Mittens", meow: () => {console.log("Mittens meows");}};
feed(mittens); // இதுவும் வேலை செய்யும், மற்றும் உண்மையான செயல்பாட்டைப் பொறுத்து மியாவ் *செய்யலாம்*.
இந்த எடுத்துக்காட்டில், feedCat
என்பது (animal: Animal) => void
என்பதன் சப்டைப் ஆகும். ஏனென்றால் feedCat
ஒரு குறிப்பிட்ட டைப்பை (Cat
) ஏற்றுக்கொள்கிறது, இது செயல்பாட்டு பாராமீட்டரில் உள்ள Animal
டைப்பைப் பொறுத்து கான்ட்ராவேரியன்ட் ஆகிறது. முக்கியமான பகுதி ஒதுக்கீடு ஆகும்: let feed: (animal: Animal) => void = feedCat;
செல்லுபடியாகும்.
திரும்பப் பெறும் டைப்கள்: கோவேரியன்ஸ்
செயல்பாட்டு ரிட்டர்ன் டைப்கள் கோவேரியன்ட் ஆகும். இதன் பொருள், எதிர்பார்க்கப்படுவதை விட ஒரு குறிப்பிட்ட டைப்பை நீங்கள் பாதுகாப்பாகத் திருப்பலாம். ஒரு செயல்பாடு ஒரு Animal
-ஐத் திருப்புவதாக உறுதியளித்தால், ஒரு Cat
-ஐத் திருப்புவது hoàn toàn ஏற்றுக்கொள்ளத்தக்கது.
function getAnimal(): Animal {
return { name: "Generic Animal" };
}
function getCat(): Cat {
return { name: "Whiskers", meow: () => { console.log("Whiskers meows"); } };
}
// இது செல்லுபடியாகும், ஏனெனில் செயல்பாட்டு ரிட்டர்ன் டைப்கள் கோவேரியன்ட்
let get: () => Animal = getCat;
let myAnimal: Animal = get();
console.log(myAnimal.name); // வேலை செய்யும்
// myAnimal.meow(); // பிழை: 'meow' பண்பு 'Animal' வகையில் இல்லை.
// Cat-க்கு குறிப்பிட்ட பண்புகளை அணுக டைப் அசெர்ஷனைப் பயன்படுத்த வேண்டும்
if ((myAnimal as Cat).meow) {
(myAnimal as Cat).meow(); // Whiskers meows
}
இங்கே, getCat
என்பது () => Animal
என்பதன் சப்டைப் ஆகும், ஏனெனில் அது ஒரு குறிப்பிட்ட டைப்பை (Cat
) திருப்புகிறது. let get: () => Animal = getCat;
என்ற ஒதுக்கீடு செல்லுபடியாகும்.
வரிசைகள் மற்றும் ஜெனரிக்ஸ்: இன்வேரியன்ஸ் (பெரும்பாலும்)
டைப்ஸ்கிரிப்ட் வரிசைகள் மற்றும் பெரும்பாலான ஜெனரிக் டைப்களை இயல்பாகவே இன்வேரியன்ட் ஆகக் கருதுகிறது. இதன் பொருள், Cat
ஆனது Animal
-ஐ விரிவுபடுத்தினாலும், Array<Cat>
ஆனது Array<Animal>
என்பதன் சப்டைப்பாகக் *கருதப்படுவதில்லை*. இது சாத்தியமான ரன்டைம் பிழைகளைத் தடுக்க ஒரு திட்டமிட்ட வடிவமைப்புத் தேர்வாகும். பல பிற மொழிகளில் வரிசைகள் கோவேரியன்ட் போல *நடந்துகொண்டாலும்*, டைப்ஸ்கிரிப்ட் பாதுகாப்பிற்காக அவற்றை இன்வேரியன்ட் ஆக்குகிறது.
let animals: Animal[] = [{ name: "Generic Animal" }];
let cats: Cat[] = [{ name: "Whiskers", meow: () => { console.log("Whiskers meows"); } }];
// பிழை: 'Cat[]' வகை 'Animal[]' வகைக்கு ஒதுக்கக்கூடியது அல்ல.
// 'Cat' வகை 'Animal' வகைக்கு ஒதுக்கக்கூடியது அல்ல.
// 'meow' பண்பு 'Animal' வகையில் இல்லை, ஆனால் 'Cat' வகையில் தேவைப்படுகிறது.
// animals = cats; // இது அனுமதிக்கப்பட்டால் சிக்கல்களை ஏற்படுத்தும்!
//இருப்பினும் இது வேலை செய்யும்
animals[0] = cats[0];
console.log(animals[0].name);
//animals[0].meow(); // பிழை - animals[0] ஆனது Animal வகையாக பார்க்கப்படுவதால் meow கிடைக்காது
(animals[0] as Cat).meow(); // Cat-க்கு குறிப்பிட்ட முறைகளைப் பயன்படுத்த டைப் அசெர்ஷன் தேவை
animals = cats;
என்ற ஒதுக்கீட்டை அனுமதிப்பது பாதுகாப்பற்றதாக இருக்கும், ஏனென்றால் நீங்கள் பின்னர் ஒரு பொதுவான Animal
-ஐ animals
வரிசையில் சேர்க்கலாம், இது cats
வரிசையின் டைப் பாதுகாப்பை மீறும் (அது Cat
பொருட்களை மட்டுமே கொண்டிருக்க வேண்டும்). இதன் காரணமாக, டைப்ஸ்கிரிப்ட் வரிசைகள் இன்வேரியன்ட் என்று ஊகிக்கிறது.
நடைமுறை எடுத்துக்காட்டுகள் மற்றும் பயன்பாட்டு வழக்குகள்
ஜெனரிக் ரெபாசிட்டரி பேட்டர்ன்
டேட்டா அணுகலுக்கான ஒரு ஜெனரிக் ரெபாசிட்டரி பேட்டர்னைக் கவனியுங்கள். உங்களிடம் ஒரு அடிப்படை என்டிட்டி டைப் மற்றும் அந்த டைப்பில் செயல்படும் ஒரு ஜெனரிக் ரெபாசிட்டரி இன்டர்ஃபேஸ் இருக்கலாம்.
interface Entity {
id: string;
}
interface Repository<T extends Entity> {
getById(id: string): T | undefined;
save(entity: T): void;
delete(id: string): void;
}
class InMemoryRepository<T extends Entity> implements Repository<T> {
private data: { [id: string]: T } = {};
getById(id: string): T | undefined {
return this.data[id];
}
save(entity: T): void {
this.data[entity.id] = entity;
}
delete(id: string): void {
delete this.data[id];
}
}
interface Product extends Entity {
name: string;
price: number;
}
const productRepository: Repository<Product> = new InMemoryRepository<Product>();
const newProduct: Product = { id: "123", name: "Laptop", price: 1200 };
productRepository.save(newProduct);
const retrievedProduct = productRepository.getById("123");
if (retrievedProduct) {
console.log(`Retrieved product: ${retrievedProduct.name}`);
}
T extends Entity
என்ற டைப் கட்டுப்பாடு, ரெபாசிட்டரி id
பண்பைக் கொண்ட என்டிட்டிகளில் மட்டுமே செயல்பட முடியும் என்பதை உறுதி செய்கிறது. இது டேட்டா ஒருமைப்பாடு மற்றும் நிலைத்தன்மையை பராமரிக்க உதவுகிறது. இந்த பேட்டர்ன் பல்வேறு வடிவங்களில் டேட்டாவை நிர்வகிக்கப் பயனுள்ளதாக இருக்கும், Product
இன்டர்ஃபேஸில் வெவ்வேறு நாணய வகைகளைக் கையாள்வதன் மூலம் சர்வதேசமயமாக்கலுக்கு ஏற்றவாறு மாற்றியமைக்கலாம்.
ஜெனரிக் பேலோடுகளுடன் நிகழ்வு கையாளுதல்
மற்றொரு பொதுவான பயன்பாட்டு வழக்கு நிகழ்வு கையாளுதல் ஆகும். நீங்கள் ஒரு குறிப்பிட்ட பேலோடுடன் ஒரு ஜெனரிக் நிகழ்வு டைப்பை வரையறுக்கலாம்.
interface Event<T> {
type: string;
payload: T;
}
interface UserCreatedEventPayload {
userId: string;
email: string;
}
interface ProductPurchasedEventPayload {
productId: string;
quantity: number;
}
function handleEvent<T>(event: Event<T>): void {
console.log(`Handling event of type: ${event.type}`);
console.log(`Payload: ${JSON.stringify(event.payload)}`);
}
const userCreatedEvent: Event<UserCreatedEventPayload> = {
type: "user.created",
payload: { userId: "user123", email: "alice@example.com" },
};
const productPurchasedEvent: Event<ProductPurchasedEventPayload> = {
type: "product.purchased",
payload: { productId: "product456", quantity: 2 },
};
handleEvent(userCreatedEvent);
handleEvent(productPurchasedEvent);
இது டைப் பாதுகாப்பைப் பராமரிக்கும் அதே வேளையில், வெவ்வேறு பேலோடு கட்டமைப்புகளுடன் வெவ்வேறு நிகழ்வு டைப்களை வரையறுக்க உங்களை அனுமதிக்கிறது. இந்த அமைப்பு உள்ளூர்மயமாக்கப்பட்ட நிகழ்வு விவரங்களை ஆதரிக்க எளிதாக விரிவுபடுத்தப்படலாம், நிகழ்வு பேலோடில் பிராந்திய விருப்பங்களை இணைத்தல், அதாவது வெவ்வேறு தேதி வடிவங்கள் அல்லது மொழி-குறிப்பிட்ட விளக்கங்கள்.
ஒரு ஜெனரிக் டேட்டா டிரான்ஸ்ஃபர்மேஷன் பைப்லைனை உருவாக்குதல்
டேட்டாவை ஒரு வடிவத்திலிருந்து மற்றொரு வடிவத்திற்கு மாற்ற வேண்டிய ஒரு சூழ்நிலையைக் கருதுங்கள். உள்ளீடு மற்றும் வெளியீடு டைப்கள் டிரான்ஸ்ஃபர்மேஷன் செயல்பாடுகளுடன் இணக்கமாக இருப்பதை உறுதிசெய்ய, டைப் பாராமீட்டர் கட்டுப்பாடுகளைப் பயன்படுத்தி ஒரு ஜெனரிக் டேட்டா டிரான்ஸ்ஃபர்மேஷன் பைப்லைனைச் செயல்படுத்தலாம்.
interface DataTransformer<TInput, TOutput> {
transform(input: TInput): TOutput;
}
function processData<TInput, TOutput, TIntermediate>(
input: TInput,
transformer1: DataTransformer<TInput, TIntermediate>,
transformer2: DataTransformer<TIntermediate, TOutput>
): TOutput {
const intermediateData = transformer1.transform(input);
const outputData = transformer2.transform(intermediateData);
return outputData;
}
interface RawUserData {
firstName: string;
lastName: string;
}
interface UserData {
fullName: string;
email: string;
}
class RawToIntermediateTransformer implements DataTransformer<RawUserData, {name: string}> {
transform(input: RawUserData): {name: string} {
return { name: `${input.firstName} ${input.lastName}`};
}
}
class IntermediateToUserTransformer implements DataTransformer<{name: string}, UserData> {
transform(input: {name: string}): UserData {
return {fullName: input.name, email: `${input.name.replace(" ", ".")}@example.com`};
}
}
const rawData: RawUserData = { firstName: "John", lastName: "Doe" };
const userData: UserData = processData(
rawData,
new RawToIntermediateTransformer(),
new IntermediateToUserTransformer()
);
console.log(userData);
இந்த எடுத்துக்காட்டில், processData
செயல்பாடு ஒரு உள்ளீடு, இரண்டு டிரான்ஸ்ஃபார்மர்களை எடுத்து, மாற்றப்பட்ட வெளியீட்டைத் திருப்புகிறது. டைப் பாராமீட்டர்கள் மற்றும் கட்டுப்பாடுகள் முதல் டிரான்ஸ்ஃபார்மரின் வெளியீடு இரண்டாவது டிரான்ஸ்ஃபார்மரின் உள்ளீட்டுடன் இணக்கமாக இருப்பதை உறுதிசெய்கிறது, இது ஒரு டைப்-பாதுகாப்பான பைப்லைனை உருவாக்குகிறது. வெவ்வேறு புலப் பெயர்கள் அல்லது டேட்டா கட்டமைப்புகளைக் கொண்ட சர்வதேச டேட்டா செட்களைக் கையாளும் போது இந்த பேட்டர்ன் விலைமதிப்பற்றதாக இருக்கும், ஏனெனில் நீங்கள் ஒவ்வொரு வடிவத்திற்கும் குறிப்பிட்ட டிரான்ஸ்ஃபார்மர்களை உருவாக்கலாம்.
சிறந்த நடைமுறைகள் மற்றும் கவனத்தில் கொள்ள வேண்டியவை
- மரபுரிமையை விட கலவையை விரும்புங்கள்: மரபுரிமை பயனுள்ளதாக இருந்தாலும், சிக்கலான டைப் உறவுகளைக் கையாளும் போது, அதிக நெகிழ்வுத்தன்மை மற்றும் பராமரிப்புக்காக கலவை மற்றும் இன்டர்ஃபேஸ்களை விரும்புங்கள்.
- டைப் கட்டுப்பாடுகளை நியாயமாகப் பயன்படுத்துங்கள்: டைப் பாராமீட்டர்களை அதிகமாகக் கட்டுப்படுத்தாதீர்கள். தேவையான டைப் பாதுகாப்பை வழங்கும் அதே வேளையில் மிகவும் பொதுவான டைப்களுக்கு முயற்சி செய்யுங்கள்.
- செயல்திறன் தாக்கங்களைக் கருத்தில் கொள்ளுங்கள்: ஜெனரிக்ஸின் அதிகப்படியான பயன்பாடு சில நேரங்களில் செயல்திறனைப் பாதிக்கலாம். எந்தவொரு இடையூறுகளையும் கண்டறிய உங்கள் கோடை சுயவிவரப்படுத்துங்கள்.
- உங்கள் கோடை ஆவணப்படுத்துங்கள்: உங்கள் ஜெனரிக் டைப்கள் மற்றும் டைப் கட்டுப்பாடுகளின் நோக்கத்தைத் தெளிவாக ஆவணப்படுத்துங்கள். இது உங்கள் கோடைப் புரிந்துகொள்வதற்கும் பராமரிப்பதற்கும் எளிதாக்குகிறது.
- முழுமையாகச் சோதிக்கவும்: உங்கள் ஜெனரிக் கோட் வெவ்வேறு டைப்களுடன் எதிர்பார்த்தபடி செயல்படுவதை உறுதிசெய்ய விரிவான யூனிட் சோதனைகளை எழுதுங்கள்.
முடிவுரை
டைப்ஸ்கிரிப்ட்டின் வேரியன்ஸ் விரிவுரைகள் (செயல்பாட்டு பாராமீட்டர் விதிகள் மூலம் மறைமுகமாக) மற்றும் டைப் பாராமீட்டர் கட்டுப்பாடுகளில் தேர்ச்சி பெறுவது வலுவான, நெகிழ்வான மற்றும் பராமரிக்கக்கூடிய கோடை உருவாக்குவதற்கு அவசியமானது. கோவேரியன்ஸ், கான்ட்ராவேரியன்ஸ் மற்றும் இன்வேரியன்ஸ் கருத்துக்களைப் புரிந்துகொண்டு, டைப் கட்டுப்பாடுகளைத் திறம்படப் பயன்படுத்துவதன் மூலம், நீங்கள் டைப்-பாதுகாப்பான மற்றும் மீண்டும் பயன்படுத்தக்கூடிய ஜெனரிக் கோடை எழுதலாம். இன்றைய உலகமயமாக்கப்பட்ட மென்பொருள் உலகில் பொதுவானது போல, பல்வேறு டேட்டா டைப்களைக் கையாள அல்லது வெவ்வேறு சூழல்களுக்கு ஏற்றவாறு மாற்றியமைக்க வேண்டிய பயன்பாடுகளை உருவாக்கும்போது இந்த நுட்பங்கள் குறிப்பாக மதிப்புமிக்கவை. சிறந்த நடைமுறைகளைக் கடைப்பிடித்து, உங்கள் கோடை முழுமையாகச் சோதிப்பதன் மூலம், நீங்கள் டைப்ஸ்கிரிப்டின் டைப் சிஸ்டத்தின் முழுத் திறனையும் திறந்து, உயர்தர மென்பொருளை உருவாக்கலாம்.