يعيّن ES6 بعض الكائنات الأصلية كفئة فرعية ، على سبيل المثال ، كائن ، منطقي ، خطأ ، خريطة ، وعد .. إلخ. الطريقة التي يتم بها نمذجة هذه البنى في lib.d.ts تجعل من المستحيل تصنيفها إلى فئة فرعية ، حيث يتم تعريفها على أنها زوج من var وواجهة.
من قسم المواصفات ES6 19.5.1:
تم تصميم مُنشئ الخطأ ليكون فئة فرعية. يمكن استخدامه كقيمة لبند ممتد من إعلان صنف. يجب أن تتضمن مُنشِئات الفئة الفرعية التي تهدف إلى وراثة سلوك الخطأ المحدد استدعاءً فائقًا لمنشئ الخطأ لتهيئة مثيلات الفئة الفرعية.
سيؤدي هذا حاليًا إلى ظهور خطأ "يمكن للفئة أن توسع فئة أخرى فقط":
class NotImplementedError extends Error {
constructor() {
super("Not Implemented");
}
}
هذه مشكلة عامة لأي مكتبة js تعرض وظائف من المفترض أن تكون مصنفة فرعية. إذا قامت مكتبتي بتصدير مُنشئ Foo وتتوقع تلقي مثيلات من الفئات الفرعية من Foo (وليس فقط الكائنات التي تنفذ واجهة تشبه Foo) ، فلا توجد حاليًا طريقة للسماح بذلك.
أود أن أقول
class Error;
لن يكون هناك جافا سكريبت منبعثة لمثل هذا البيان ، فقط تحديث لجدول رموز التنصيب.
بالنسبة للحالة العامة ، أود أن أتمكن من استبدال نص أي إعلان فئة بفاصلة منقوطة ، مع السماح بأشياء مثل
class Foo<X, Y> extends Bar<X> implements Baz<Y>;
مما يعني أن المكتبة تضمن بالفعل أن Foo.prototype هو مثيل لـ Bar.prototype ويقوم بتنفيذ واجهة Baz.
metaweta @ أعتقد أنه قد يحدث بعض التكرار:
interface Foo {
}
class Foo; // Foo is now a class!
interface Bar extends Foo {
}
class Bar extends Foo; // Two `extends Foo`s.
interface X {
}
class X extends Foo; // Hmm?
interface Y extends Foo {
}
class Y; // Hmm?
لا يزال لديها بعض الإمكانات لأن الواجهات ذات التصنيف الفرعي ستعمل كصفوف مفتوحة. # 819
metaweta يجب التعامل مع قضيتك الأولى من خلال إعلان فئة البيئة المحيطة. على سبيل المثال
// myLib.d.ts
declare class Error {
}
// no code emitted here for this.
// myfile.ts
// Error is subclassable,
class MyError extends Error {
}
بالنسبة للحالة الثانية ، أود تقديم مشكلة اقتراح مختلفة لها.
فيما يلي القائمة الكاملة للكائنات "ذات التصنيف الفرعي" من مواصفات ES6. حاليًا يتم تعريف كل هذه على أنها أزواج واجهة / var.
مشاكل:
الحلول الممكنة:
mhegazy شكرًا ، لم أكن على دراية ببناء إعلان الطبقة المحيطة.
عندما أقوم بتوسيع فئة Error بهذه الطريقة (باستخدام تعريف الفئة المحيطة) ، فإن إلقاء الخطأ ExtendedError لا ينتج عنه تتبع مكدس ولا يعين الرسالة بشكل صحيح.
declare class Error {
constructor(message?: string);
}
class ExtendedError extends Error {
constructor(message?: string) {
super(message + " extended");
}
}
//throw new Error("Test");
throw new ExtendedError("Test");
unional هذا يبدو وكأنه مشكلة في المحرك. يجب أن يعمل وفقًا لمواصفات ES6. يجب أن تصلح المحركات هذه الآن بعد أن تم التصديق على ES6.
تمكنت من جعله يعمل. في كود js الذي كان يعمل ، لدي استدعاء Error.captureStackTrace ولكني أخرجه عندما أقوم بتطبيقه في ts لأن إعلان الخطأ لا يحتوي عليه.
يوجد مثال على الكود:
إنه استثناء يشبه C # يأخذ استثناءً داخليًا.
declare class Error {
public name:string;
public message:string;
public stack:string;
constructor(message?:string);
static captureStackTrace(error: Error, constructorOpt: any);
}
class Exception extends Error {
public innerException: Error;
constructor(message?: string, innerException?: Error|string) {
// Guard against throw Exception(...) usage.
if (!(this instanceof Exception)) return new Exception(message, innerException);
super();
if (typeof Error.captureStackTrace === 'function') {
//noinspection JSUnresolvedFunction
Error.captureStackTrace(this, arguments.callee);
}
this.name = "Exception";
if (innerException) {
if (innerException instanceof Error) {
this.innerException = innerException;
this.message = message + ", innerException: " + this.innerException.message;
}
else if (typeof innerException === "string") {
this.innerException = new Error(innerException);
this.message = message + ", innerException: " + this.innerException.message;
}
else {
this.innerException = innerException;
this.message = message + ", innerException: " + this.innerException;
}
}
else {
this.message = message;
}
}
}
تم الإصلاح بواسطة # 3516. يمكن للفئات الآن توسيع التعبيرات العشوائية لأنواع دالة المنشئ.
ما هو إصدار TypeScript الذي سيتم شحن هذا الإصلاح؟
لقد تحققت بسرعة من ملصقات الإصدار لـ 1.5.3 و 1.5.4 ، ويبدو أنه لم يتم شحنها بعد ، فقط في الإصدار الرئيسي في الوقت الحالي.
تعديل:
عذرًا ، لقد لاحظنا الآن أن الخطأ تم تمييزه بواسطة المعلم الرئيسي "TypeScript 1.6"
شكرا لعملكم!
kostrse يمكنك تجربة إصداراتنا الليلية من TypeScript 1.6 من خلال تشغيل npm install -g typescript@next
.
مرحبا،
أنا أستخدم Typescript 1.6.2 ويظهر lib.es6.d.ts الخاص بي خطأ (و Array
هل هذا ثابت بالفعل في 1.6.2؟
في صحتك!
jpsfs الإصلاح ، كما أشار ahejlsberg في https://github.com/Microsoft/TypeScript/issues/1168#issuecomment -112955503 هو السماح للفئات بتوسيع التعبيرات العشوائية لأنواع وظائف المُنشئ.
حتى أن هناك إمكانية لتوسيع فئة Error
الأيام ، ما زلت أواجه إزعاجًا في العقدة. على سبيل المثال ، أواجه مشكلات مع "error.stack". عندما أحصل على throw new Error(...)
أحصل على error.stack
، لكن عندما أحصل على throw new CustomError()
- لا أفعل. لحلها أجبرت على استخدام هذه الحيلة:
export class HttpError extends Error {
httpCode: number;
message: string;
constructor(httpCode: number, message?: string) {
super();
if (httpCode)
this.httpCode = httpCode;
if (message)
this.message = message;
this.stack = new Error().stack;
}
}
التعليق الأكثر فائدة
حتى أن هناك إمكانية لتوسيع فئة
Error
الأيام ، ما زلت أواجه إزعاجًا في العقدة. على سبيل المثال ، أواجه مشكلات مع "error.stack". عندما أحصل علىthrow new Error(...)
أحصل علىerror.stack
، لكن عندما أحصل علىthrow new CustomError()
- لا أفعل. لحلها أجبرت على استخدام هذه الحيلة: