typescript - 打字稿中的“扩展”实际上是什么意思?
问题描述
在联合类型的情况下,我无法完全掌握 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;
};
我们如何解决这个问题。
解决方案
extends
函数中的T
包含指定类型的子类型。对于工会来说,子类型的含义可能有点令人惊讶。
您必须考虑子类型关系的真正含义。当我们说那SomeExtendedClass
是一个子类时SomeClass
,意味着任何SomeExtendedClass
一个实例也是一个实例SomeClass
所以所有SomeClass
实例的集合包含所有实例的集合SomeExtendedClass
。
但是,如果我们采用联合子类型的这种观点,我们会看到成员较少的联合 ( "a" | "b"
) 实际上是成员较多的联合的子类型 ( "a" | "b" | "c"
),因为 的所有实例"a" | "b"
都是 的实例"a" | "b" | "c"
。
我们直观地认为子类型是“有更多东西”的子类型,但是当考虑联合时,这种直觉让我们失望了,我们需要从集合的角度来考虑子类型的关系。
推荐阅读
- reactjs - 如何在不使用 onMouseOut 和 onMouseHover 的情况下通过 CSS 文件将图像悬停在 ReactJs 中
- batch-file - 批处理文件命令执行超时
- python - 使用 S3 文件中的记录来访问 API 端点
- oauth - google calendar api - 更改现有推送通知渠道的 web_hook 地址
- clojure - 不进行分块的“序列”版本
- javascript - 如何使用 vanilla JS Web Components 从子组件引用父组件中的方法?(不是任何框架或库)
- python - 处理大数据(xls、csv、google sheet)并将其存储在数据库中
- navigation - 从包文件构建地图时“等待地图”但没有任何反应
- android - 动态更改 SwitchMaterial 颜色
- python - 在 Python 中解包字典