打字稿中的“扩展"实际上是什么意思?
在联合类型的情况下,我无法完全掌握 extends 关键字的使用.这是一段代码片段,解释了我的困惑.
I am not able to fully grasp the use of extends keyword in case of union types. Here is a code snippet explaining the confusion that I have.
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)
所以我想知道为什么要做出这样的设计决定以及相同的含义是什么.
So I was wondering why such design decisions are made and what are the implications of the same.
改变function someTypeFunction
到function someTypeFunction
工作,但我无法理解这件事实际上是如何工作的.
changing
function someTypeFunction<T extends someType>(args: T): T {return args;};
to
function someTypeFunction<T extends someExtendedType>(args: T): T {return args;};
works but I am not able to understand how this thing is actually working.
编辑 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;
};
我们如何解决这个问题.
How do we resolve this.
函数中的 extends
将 T
包含为指定类型的子类型.对于联合来说,子类型的含义可能有点令人惊讶.
The extends
in the function constains T
to be a subtype of the specified type. What a subtype means may be a bit surprising for unions.
您必须考虑子类型关系的真正含义.当我们说 SomeExtendedClass
是 SomeClass
的子类时,其含义是 SomeExtendedClass
的任何实例也是 SomeClass的实例代码>
You have to think of what a subtype relationship really means. When we say that SomeExtendedClass
is a subclass of SomeClass
the implication is that any instance of SomeExtendedClass
is also an instance of SomeClass
所以所有 SomeClass
实例的集合包含所有 SomeExtendedClass
实例的集合.
So the set of all SomeClass
instances contains the set of all SomeExtendedClass
instances.
但是,如果我们将这种子类型的观点视为联合,我们会看到成员较少的联合 ("a" | "b"
) 实际上是成员较多的联合 ("a" | "b" | "c"
) 因为 "a" | 的所有实例"b"
是 "a" | 的实例"b" |"c"
.
But if we take this view of subtypes to unions we see that the union with fewer memebers ("a" | "b"
) is actually subtype of the one with more members ("a" | "b" | "c"
) since all instances of "a" | "b"
are instances of "a" | "b" | "c"
.
我们直觉上认为子类型是有更多东西"的类型,但是当考虑联合时,这种直觉使我们失望,我们需要从集合的角度考虑子类型关系.
We intuitively think the subtype is the one that "has more stuff" but when thinking about unions this intuition fails us , we need to think about the subtype relationship in terms of sets.