تایپاسکریپت - نوع یک کلاس فرزند از یک کلاس انتزاعی والد با یک کارخانهٔ استاتیک


من میخواهم به نوع یک کلاس ارجاع دهم که یک کلاس انتزاعی را گسترش میدهد و یک تابع کارخانهای ایستا دارد که در والد انتزاعی آن پیادهسازی شده است.

من یاد گرفتم چگونه در کلاسهای انتزاعی کارخانههای استاتیک بنویسم اینجا: https://stackoverflow.com/a/65717206/923846.

لطفاً این کد را در نظر بگیرید:

abstract class Parent {
    public static factory<T extends Parent>(this: new (...args: any[]) => T) {
        return new this();
    }
}

class Child1 extends Parent { }
class Child2 extends Parent { }

// what specific type can i use instead of "any" here:
const arr: any[] = [ Child1, Child2 ];

let child1 = arr[0].factory();
let child2 = arr[1].factory();

من از نوع any عناصر در arr استفاده کردم.

من میخواهم از یک نوع خاص استفاده کنم.

من سعی کردم آن را اینطور اعلام کنم:

type TParent = typeof Parent;

...

const arr: TParent[] = [ Child1, Child2 ];

...

// i get an error for this line:
let child1 = arr[0].factory();

من خطای «نمیتوان یک نوع سازنده انتزاعی را به یک نوع سازنده غیرانتزاعی اختصاص داد» را دریافت میکنم.

پس چگونه این نوع را اعلام کنیم؟

پاسخ شماره ۱

در این حالت سادهترین کار این است که تایپاسکریپت نوعها را استنتاج کند و از as const استفاده کند (playground):

const arr = [ Child1, Child2 ] as const;

let child1 = arr[0].factory(); // type Child1
let child2 = arr[1].factory(); // type Child2

برای یک نوع عمومی، ما نیاز داریم که نوع abstract constructor را حذف کنیم و آن را به یک نوع عادی تغییر دهیم تا بتوانیم از طریق new this() نمونهسازی کنیم (playground):

// convert the abstract constructor to a normal one and add the static functions via typeof Parent
type ParentSubClass = {new() : Parent} & (typeof Parent);

const arr: ParentSubClass[] = [ Child1, Child2 ];

let child1 = arr[0].factory(); // type Parent
let child2 = arr[1].factory(); // type Parent