在打字稿中“扩展”实际上意味着什么?

Amo*_*pta 1 typescript typescript-typings

在联合类型的情况下,我无法完全掌握 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)
Run Code Online (Sandbox Code Playgroud)

所以我想知道为什么要做出这样的设计决策以及其含义是什么。

更改 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;
};
Run Code Online (Sandbox Code Playgroud)

我们如何解决这个问题。

Tit*_*mir 5

函数extends中的 包含T为指定类型的子类型。对于工会来说,子类型的含义可能有点令人惊讶。

您必须考虑子类型关系的真正含义。当我们说它SomeExtendedClass是 的子类时SomeClass,意味着任何 的实例SomeExtendedClass也是 的实例SomeClass

所以所有实例的集合SomeClass包含所有实例的集合SomeExtendedClass

在此输入图像描述

但是,如果我们采用联合子类型的这种观点,我们会发现成员较少的联合 ( "a" | "b") 实际上是成员较多的联合 ( "a" | "b" | "c") 的子类型,因为 的所有实例"a" | "b"都是 的实例"a" | "b" | "c"

在此输入图像描述

我们直观地认为子类型是“有更多东西”的子类型,但是当考虑并集时,这种直觉让我们失败了,我们需要从集合的角度来考虑子类型关系。