إصدار TypeScript: 2.2.2
قد أكون مجرد سوء فهم لكيفية عمل الأدوية الجنيسة (إذا كان الأمر كذلك ، يرجى توجيهي إلى الاتجاه الصحيح) ، لكن هذا يبدو وكأنه خطأ.
رمز
// A *self-contained* demonstration of the problem follows...
interface BaseState {
on: boolean;
};
class Component {
state: BaseState;
setState(state: BaseState) {
this.state = state;
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // no error
}
}
class GenericComponent<State extends BaseState> {
state: State;
setState(state: State) {
this.state = state
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // error Argument of type '{ on: boolean; }' is not assignable to parameter of type 'State'.
}
}
سلوك متوقع:
في فئة Component
في المثال أعلاه ، لا تسبب أي أخطاء عند استخدام واجهة BaseState
مباشرة. أتوقع نفس السلوك من فئة GenericComponent
لأن الفئة العامة State
تمتد صراحة إلى BaseState
.
السلوك الفعلي:
بدلاً من ذلك ، تلقيت الخطأ التالي المتعلق بـ this.setState({ on: value > 0 });
: "الوسيطة من النوع '{on: boolean؛}' غير قابلة للتخصيص إلى معلمة من النوع 'State'."
ضع في اعتبارك ما يحدث إذا كتبت هذا
var t = new GenericComponent<{on: boolean, thing: string}>();
t.onInput({ value: 30 });
t.state.thing.substr(0); // 'thing' property should exist, but doesn't
هذا مثال مبسط:
class Stateful<State extends { on: boolean }> {
state: State = {
on: true
}; // error
}
سبب عدم نجاح ذلك هو أنه سيكون صالحًا فقط عندما يتم إنشاء مثيل Stateful
باستخدام وسيطة من النوع تعادل بالضبط { on: boolean }
.
في الأساس ، _ يوجد_ نوع T
، يفي بقيود وسيطة نوع Stateful
مثل أن إنشاء مثيل صالح ولكن هذا لا ينطبق _ لجميع_ الأنواع T
حيث T
يلبي Stateful
.
لذلك يؤكد الرمز الخاطئ أعلاه ، بالنسبة لجميع الأنواع ، T<T>
حيث T,
Stateful
منطقيا ، يمكننا النظر إليه على النحو التالي
تأكيد
P
من النوع { on: boolean }
T
مثل أن T
قابل للتخصيص لـ P
، تعريف Stateful<T>
أعلاه صالحالنقض من خلال مثال مضاد
U
من النوع { on: boolean, value: number }
U
قابل للتخصيص لـ P
-> حسب التعريفStateful<U>
غير صالح -> بالتعويضT
مثل أن T
قابل للتخصيص إلى P
و Stateful<T>
هو مثيل غير صالح -> ضمنيًاRyanCavanaughaluanhaddad تبادل لاطلاق النار، وأنا أعرف ذلك. لقد أصبت بالارتباك أثناء محاولتي اختزال المشكلة إلى شيء أبسط لذا دعونا نحاول ذلك مرة أخرى. ماذا عن استخدام الجزئي في هذه الحالة؟ ما زلت أحصل على خطأ مماثل.
interface BaseState {
on: boolean;
};
class Component {
state: BaseState;
setState(partialState: Partial<BaseState>) {
this.state = { ...this.state, ...partialState };
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // no error
}
}
class GenericComponent<State extends BaseState> {
state: State;
setState(partialState: Partial<State>) {
this.state = { ...this.state, ...partialState };
}
onInput({ value }: { value: number }) {
this.setState({ on: value > 0 }); // error: Argument of type '{ on: boolean; }' is not assignable to parameter of type 'Partial<State>'
}
}
التعليق الأكثر فائدة
ضع في اعتبارك ما يحدث إذا كتبت هذا