为什么在e4
,e5
,e6
中出现错误?它们都匹配SomeClass
类型,因此必须匹配通用RES
。
class SomeClass {
a: string;
b: number;
c: boolean;
}
class ChildOfSomeClass extends SomeClass {}
const someFunc1 = <RES extends SomeClass>() => {
const e1: SomeClass = { a: "aaa", b: 123, c: true }; // ok
const e2: SomeClass = new SomeClass(); // ok
const e3: SomeClass = new ChildOfSomeClass(); // ok
// Type '{ a: string; b: number; c: true; }' is not assignable to type 'RES'.ts(2322)
const e4: RES = { a: "aaa", b: 123, c: true };
// Type 'SomeClass' is not assignable to type 'RES'.ts(2322)
const e5: RES = new SomeClass();
// Type 'ChildOfSomeClass' is not assignable to type 'RES'.ts(2322)
const e6: RES = new ChildOfSomeClass();
};
我最终希望someFunc1
返回RES | Promise<RES>
,但是为了示例起见,我简化了它。
答案 0 :(得分:2)
RES extends SomeClass
表示类型RES
描述的值集是类型SomeClass
描述的值集的子集。想象以下情况:
class MyRES extends SomeClass {
d: string;
}
这满足条件RES extends SomeClass
,但是在您提供的所有构造方法中,都没有分配d
。
有很多方法可以解决此问题,“正确”的解决方案将取决于您要使用此方法完成的工作。例如,一种解决方案是使您的方法采用一些构造函数或转换器方法,以根据RES
的已知现有属性创建一个SomeClass
:
const someFunc1 = <RES extends SomeClass>(toRes: (SomeClass) => RES) => {
const e: RES = toRes({ a: "aaa", b: 123, c: true }); // ok
};
答案 1 :(得分:1)
这是因为RES
扩展了 SomeClass
。想象一下:
class SomeClass {
a: string;
b: number;
c: boolean;
}
class ChildOfSomeClass extends SomeClass {}
class OtherChild extends SomeClass { d: string }
并假设RES
是OtherChild
(确实扩展了SomeClass
),您的代码将如下所示:
const someFunc1 = () => {
const e1: SomeClass = { a: "aaa", b: 123, c: true }; // ok
const e2: SomeClass = new SomeClass(); // ok
const e3: SomeClass = new ChildOfSomeClass(); // ok
const e4: OtherChild = { a: "aaa", b: 123, c: true }; // Not OK, OtherChild needs d
// Downcasting SomeClass to OtherChild is not ok
const e5: OtherChild = new SomeClass();
const e6: OtherChild = new ChildOfSomeClass(); //This is especially not OK
};
您可以通过仅使用SomeClass
来解决此问题,然后可以传递任何子对象。