在联合类型的情况下,我无法完全掌握extends关键字的用法。 这是一个代码片段,解释了我的困惑。
class SomeClass {
someClassProp: string;
};
class SomeExtendedClass extends SomeClass {
someExtendedClassProp: string;
};
function someClassFunction<T extends SomeClass>(args: T): T {
return args;
};
let someClass: SomeClass, someExtendedClass: SomeExtendedClass;
someClassFunction(someClass);
someClassFunction(someExtendedClass); // Works just fine(case 1)
type someType = 'a' | 'b';
type someExtendedType = someType | 'c';
function someTypeFunction<T extends someType>(args: T): T {
return args;
};
let someType: someType, someExtendedType: someExtendedType;
someTypeFunction(someType);
someTypeFunction(someExtendedType); // Gives me an error(case 2)
所以我想知道为什么要做出这样的设计决定,以及它的含义是什么。
变化中
function someTypeFunction<T extends someType>(args: T): T {return args;};
至
function someTypeFunction<T extends someExtendedType>(args: T): T {return args;};
可以,但是我不明白这东西是如何工作的。
编辑1
type someType = 'a' | 'b';
type someOtherType = 'c';
type someUnionType = someType | someOtherType;
type someTypeCore<T extends someUnionType> = { type: T };
type someTypeObj<T extends someType> = { a: string } & someTypeCore<T>;
type someOtherTypeObj<T extends someOtherType> = { b: string, c: string } & someTypeCore<T>;
function typeAssertion<T extends someUnionType>(args: someTypeCore<T>): args is someTypeObj<T> {
return (args as someTypeObj<T>).a !== undefined; // Gives an error
};
function someTypeFunction<T extends someUnionType>(args: someTypeCore<T>): T {
if (typeAssertion(args)) {
// Do something for someTypeObj
} else {
// Do Something for someOtherTypeObj
};
return args.type;
};
我们如何解决这个问题。
答案 0 :(得分:2)
函数中的extends
包含T
是指定类型的子类型。对于工会,子类型的含义可能有些令人惊讶。
您必须考虑子类型关系的真正含义。当我们说SomeExtendedClass
是SomeClass
的子类时,就意味着SomeExtendedClass
的任何实例也是SomeClass
的实例
因此,所有SomeClass
实例的集合包含所有SomeExtendedClass
实例的集合。
但是,如果我们从这种对联合的子类型的观点来看,我们会发现成员("a" | "b"
)少的联合实际上是成员("a" | "b" | "c"
)多的联合的子类型,因为所有{{ 1}}是"a" | "b"
的实例。
我们直观地认为子类型是“拥有更多东西”的子类型,但是当考虑到联合时,这种直觉使我们失败了,我们需要根据集合来考虑子类型的关系。