← Back to TypeScript Course | Chapter 22: Mixins | Lesson 3 of 4

Constrained Mixins की जानकारी

एक constrained mixin base class से particular properties या methods provide करने की मांग करता है। Generic constraints TypeScript को verify करने देते हैं कि एक mixin सिर्फ compatible classes receive करे।
Syntax
typescript
function MixinName<TBase extends Constructor<Required>>(Base: TBase) {
  return class extends Base {
    // can use members of Required
  };
}

Why Constrain a Mixin?

एक mixin को कभी-कभी कुछ उपयोगी जोड़ने से पहले base class पर पहले से मौजूद एक specific property या method चाहिए होता है — एक structural constraint उस requirement को explicit और TypeScript से checkable बना देता है।

उदाहरण: Why Constrain a Mixin?

typescript
interface HasName { name: string; }
type Constructor<T = {}> = new (...args: any[]) => T;
function Greetable<TBase extends Constructor<HasName>>(Base: TBase) {
  return class extends Base {
    greet() { return `Hello, ${this.name}`; }
  };
}
class Person { name = "Ravi"; }
class GreetablePerson extends Greetable(Person) {}
console.log(new GreetablePerson().greet());

Constraining with Interfaces

एक interface exactly describe कर सकता है कि base class के पास पहले से कौन सी capability होनी चाहिए; mixin का constructor-type parameter फिर उस requirement enforce करने के लिए उस interface को एक construct signature के साथ combine करता है।

उदाहरण: Constraining with Interfaces

typescript
interface Timestamped { createdAt: Date; }
type Constructor<T = {}> = new (...args: any[]) => T;
function Auditable<TBase extends Constructor<Timestamped>>(Base: TBase) {
  return class extends Base {
    age() { return Date.now() - this.createdAt.getTime(); }
  };
}
class Record_ { createdAt = new Date(); }
class AuditableRecord extends Auditable(Record_) {}
console.log(typeof new AuditableRecord().age());

Constrained Method Requirements

एक mixin एक field के बजाय एक specific method require कर सकता है — constraint यह सुनिश्चित करता है कि base class actually एक callable member expose करे जो mixin internally depend करने वाले signature से match करे।

उदाहरण: Constrained Method Requirements

typescript
interface Serializable { serialize(): string; }
type Constructor<T = {}> = new (...args: any[]) => T;
function Loggable<TBase extends Constructor<Serializable>>(Base: TBase) {
  return class extends Base {
    log() { console.log(this.serialize()); }
  };
}
class Data {
  serialize() { return "data payload"; }
}
class LoggableData extends Loggable(Data) {}
new LoggableData().log();

Multiple Constraints

जब एक mixin एक साथ कई capabilities पर depend करता है, उन्हें एक single interface में combine करें — pass किया गया base class उस combined interface के हर member को satisfy करना चाहिए, सिर्फ कुछ को नहीं।

उदाहरण: Multiple Constraints

typescript
interface HasName { name: string; }
interface HasAge { age: number; }
type Constructor<T = {}> = new (...args: any[]) => T;
function Describable<TBase extends Constructor<HasName & HasAge>>(Base: TBase) {
  return class extends Base {
    describe() { return `${this.name}, age ${this.age}`; }
  };
}
class Person { name = "Ravi"; age = 25; }
class DescribablePerson extends Describable(Person) {}
console.log(new DescribablePerson().describe());

Benefits of Constrained Mixins

Constraints reliability improve करते हैं क्योंकि एक incompatible base class runtime पर mysteriously fail होने के बजाय compile time पर reject हो जाती है, और वे यह documentation भी देते हैं कि mixin अपने input से exactly क्या expect करता है।

उदाहरण: Benefits of Constrained Mixins

typescript
interface HasId { id: number; }
type Constructor<T = {}> = new (...args: any[]) => T;
function Findable<TBase extends Constructor<HasId>>(Base: TBase) {
  return class extends Base {
    key() { return `record-${this.id}`; }
  };
}
class Entity { id = 1; }
class FindableEntity extends Findable(Entity) {}
console.log(new FindableEntity().key());
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. एक mixin को एक ऐसी base class पर उपयोग करना जिसमें required property न हो, जैसे name, जो compile fail होता है।
  2. सिर्फ Constructor से constrain करना और फिर mixin के अंदर this.name उपयोग करना, जो एक error है।
  3. TBase extends HasName लिखना बजाय TBase extends Constructor<HasName> के, क्योंकि constraint को एक class describe करना चाहिए, एक instance नहीं।
🔒

Chapter Quiz — Complete all 4 topics to unlock

0/4 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.